68. Django | Authorized content - MantsSk/CA_PTUA14 GitHub Wiki

Vartotojai - autorizuotas turinys

Pagrindinis dinaminių tinklalapių požymis - jų gebėjimas bendrauti su kiekvienu vartotoju atskirai, pateikiant jam aktualų turinį. Mūsų atveju, tinklalapio vartotojai bus bibliotekos skaitytojai. Mes jau esame pertavarkę base.html taip, kad vartotojai matytų jog yra prisijungę.

pamėginkime pertvarkyti BookInstance modelį taip, kad kiekviena paimta kopija būtų priskirta tam tikram vartotojui. Pirmiausiai, į models.py* importuokime User klasę, bei datetime biblioteką.

from django.contrib.auth.models import User
from datetime import date

tuomet papildykime klasę BookInstance skaitytoju:

reader = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)

...ir viską numigruokime.

Skaitytojo laukelį integruokime ir į administratoriaus svetainę:

class BookInstanceAdmin(admin.ModelAdmin):
    list_display = ('book', 'status', 'due_back')
    list_filter = ('status', 'due_back')
    list_editable = ('due_back', 'status')
    search_fields = ('id', 'book__title')

    fieldsets = (
        ('General', {'fields': ('id', 'book')}),
        ('Availability', {'fields': ('status', 'due_back', 'reader')}),
    )

Rezultatas atrodys taip: image

Dabar administratorius gali 'išrašinėti' skaitytojams knygas, ta proga paskolinkime skaitytojams keletą egzempliorių.

Dabar pats metas sukurti view'są, kuriame prisijungęs vartotojas matys savo paimtas knygas.

views.py:

class LoanedBooksByUserListView(LoginRequiredMixin, generic.ListView):
    model = BookInstance
    template_name = 'user_books.html'
    paginate_by = 10

    def get_queryset(self):
        return BookInstance.objects.filter(reader=self.request.user).filter(status__exact='t').order_by('due_back')

šiek tiek paaiškinimų:

importuojame LoginRequiredMixin, ir keliame jį į klasės parametrus. Jis django nurodo, kad *view'*sas bus prieinamas tik prisiregistravusiam vartotojui. Jei naudotumėm funkcinį view'są, prieš jį dėtumėm dekoratorių @login_required.

override'inam get_queryset funkciją ir nurodome, kad Bookinstance modelį filtruosime pagal prisiregistravusį skaitytoją, pagal statusą 'p'(paimta), ir išrūšiuosime pagal due_back lauką.

užregistruokime view'są urls.py:

path('mybooks/', views.LoanedBooksByUserListView.as_view(), name='my-borrowed')

Reikės šablono:

{% extends "base.html" %}

{% block content %}
    <h1>Mano paimtos knygos</h1>

    {% if bookinstance_list %}
    <ul>

      {% for bookinst in bookinstance_list %} 
      <li>
        <a href="{% url 'book-detail' bookinst.book.pk %}">{{bookinst.book.title}}</a> ({{ bookinst.due_back }})        
      </li>
      {% endfor %}
    </ul>

    {% else %}
      <p>Šiuo metu iš mūsų nesate paėmę knygų.</p>
    {% endif %}       
{% endblock %}

Belieka tik įdėti nuorodą į aukščiau sukurtą šabloną faile base.html:

        <li><a href="{% url 'books' %}">Books</a></li>
        <li><a href="{% url 'my-borrowed' %}">My Books</a></li>

HTML laukai modeliuose

Tokios platformos, kaip django, atrodytų turi viską, ko gali panorėti programuotojas, bet pralaimi elementariam wordpress'ui, kai reikia pasigaminti paprasčiausią blogą, nes negalime prigaminti straipsnių, taip, kad viename paveikslėliai būtų trys ir būtent tose vietose, kur norime, o kitame galbūt nebūtų nei vieno. O kitame galbūt video kaip nors įterptas. Kaip turėtų atrodyti mūsų straipsnio modelis?

Čia į pagalbą mums ateina trečių šalių paketai. Vienas iš tokių yra TinyMCE. Išbandykime:

pip install django-tinymce

settings.py faile, prie instaliuotų programų sąrašo pridėkime:

INSTALLED_APPS = (
    ...
    'tinymce',
)

mysite/urls.py papildykime:

urlpatterns = [
   path('library/', include('library.urls')),
   path('admin/', admin.site.urls),
   path('', RedirectView.as_view(url='library/', permanent=True)),
   path('accounts/', include('django.contrib.auth.urls')),
   path('tinymce/', include('tinymce.urls')),
] + (static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) +  
   static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT))

sakykime, kad norime autorių aprašymus daryti pilno straipsnio pobūdžio. Mums reikės pakoreguoti modelį Author:

from tinymce.models import HTMLField

description = HTMLField()

Administratoriaus svetainėjė turime tokį rezultatą:

image

Pats paprasčiausias TinyMCE variantas, be papildomų konfigūracijų duoda mums teksto formatavimo galimybę. Bet mes norime daugiau :)

settings.py papildykime TinyMCE nustatymais:

TINYMCE_DEFAULT_CONFIG = {
    'height': 360,
    'width': 1120,
    'cleanup_on_startup': True,
    'custom_undo_redo_levels': 20,
    'selector': 'textarea',
    'plugins': '''
            textcolor save link image media preview codesample contextmenu
            table code lists fullscreen  insertdatetime  nonbreaking
            contextmenu directionality searchreplace wordcount visualblocks
            visualchars code fullscreen autolink lists  charmap print  hr
            anchor pagebreak
            ''',
    'toolbar1': '''
            fullscreen preview bold italic underline | fontselect,
            fontsizeselect  | forecolor backcolor | alignleft alignright |
            aligncenter alignjustify | indent outdent | bullist numlist table |
            | link image media | codesample |
            ''',
    'toolbar2': '''
            visualblocks visualchars |
            charmap hr pagebreak nonbreaking anchor |  code |
            ''',
    'contextmenu': 'formats | link image',
    'menubar': True,
    'statusbar': True,
    }

Ką reiškia kiekvienas nustatymas, galite pasiskaityti dokumentacijoje

bet iš esmės - plugins yra tas skyrelis, kuris aktyvuoja viduje surašytus TinyMCE įskiepius.

image

Dabar jau turime pilną redaktorių su meniu, kurį galime išsididinti fullscreen ir dirbti tarsi su Word programa. Pamėginkime :) Bet prieš tai django nurodykime, kad šie pakeitimai yra saugūs. Django nelabai nori leisti programoms iš išorės daryti html įterpimus. Pakoreguokime author.html:

<p>{{ author.description | safe }}</p>

image

⚠️ **GitHub.com Fallback** ⚠️