Serwer WWW na przykªadzie Django cz.3 Krzysztof Ciebiera 20 kwietnia 2010 Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 1 / 34
1 Formularze 2 Ciasteczka 3 Sesje 4 U»ytkownicy Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 2 / 34
Najprostszy formularz def search(request): query = request.get.get('q', '') if query: qset = (Q(title icontains=query)... ) results = Book.objects.filter(qset).distinct() else: results = [] return render_to_response("books/search.html", { "results": results, "query": query }) Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 3 / 34
Formularz - u»ycie <title>search{% if query %} Results{% endif %}... <h1>search</h1> <form action="." method="get"> <label for="q">search: </label> <input type="text" name="q" value="{{ query escape }}"> <input type="submit" value="search">... {% if query %} <h2>results for "{{ query escape }}":</h2> {% if results %} <ul> {% for book in results %} <li>{{ book escape }}</l1> {% endfor %} Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 4 / 34
Idealny formularz W formularzu wprowadza si dane, które s opisane (np. <label>) Dane s werykowane W przypadku bª du u»ytkownik mo»e poprawi dane Formularz wy±wietla si wielokrotnie, a» wszystkie dane s poprawne Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 5 / 34
forms.py from django import newforms as forms TOPIC_CHOICES = ( ('general', 'General enquiry'), ('bug', 'Bug report'), ('suggestion', 'Suggestion'), ) class ContactForm(forms.Form): topic = forms.choicefield(choices=topic_choices) message = forms.charfield() sender = forms.emailfield(required=false) Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 6 / 34
Widok from forms import ContactForm def contact(request): form = ContactForm() return render_to_response('contact.html', {'form': form}) Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 7 / 34
Szablon <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="en"> <head> <title>contact us</title></head> <body> <h1>contact us</h1> <form action="." method="post"> <table> {{ form.as_table }} </table> <p><input type="submit" value="submit"></p> </form> </body> </html> Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 8 / 34
Jak to wygl da Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 9 / 34
forms.py from django import newforms as forms TOPIC_CHOICES = ( ('general', 'General enquiry'), ('bug', 'Bug report'), ('suggestion', 'Suggestion'), ) class ContactformForm(forms.Form): topic = forms.choicefield(choices=topic_choices) message = forms.charfield(widget = forms.textarea()) sender = forms.emailfield(required=false) Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 10 / 34
Jak to wygl da Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 11 / 34
Walidacja def contact(request): if request.method == 'POST': form = ContactForm(request.POST) else: form = ContactForm() return render_to_response('contact.html', {'form': form}) Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 12 / 34
Zachowanie 1 def contact(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): topic = form.clean_data['topic'] message = form.clean_data['message'] sender = form.clean_data.get('sender', 'noreply@example.com') Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 13 / 34
Zachowanie 2 send_mail( 'Feedback from your site, topic: %s' % topic, message, sender, ['administrator@example.com'] ) return HttpResponseRedirect('/contact/thanks/') else: form = ContactForm() return render_to_response('contact.html', {'form': form}) Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 14 / 34
Wªasna walidacja class ContactForm(forms.Form): topic = forms.choicefield(choices=topic_choices) message = forms.charfield(widget=forms.textarea()) sender = forms.emailfield(required=false) def clean_message(self): message = self.clean_data.get('message', '') num_words = len(message.split()) if num_words < 4: raise forms.validationerror("not enough words!") return message Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 15 / 34
Inne wykorzystanie formularzy from models import Publisher from django.newforms import form_for_model PublisherForm = form_for_model(publisher) ==== def add_publisher(request): if request.method == 'POST': form = PublisherForm(request.POST) if form.is_valid(): form.save() return HttpResponseRedirect('/add_publisher/thanks/ Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 16 / 34
Odczytywanie ciasteczek def show_color(request): if "favorite_color" in request.cookies: return HttpResponse("Your favorite color is %s" % \ request.cookies["favorite_color"]) else: return HttpResponse("You don't have a favorite color.") Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 17 / 34
Ustawianie ciasteczek def set_color(request): if "favorite_color" in request.get: response = HttpResponse("Your favorite color is now %s" request.get["favorite_color"]) response.set_cookie("favorite_color", request.get["favorite_color"]) return response else: return HttpResponse("You didn't give a favorite color." Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 18 / 34
Werykacja ciasteczek def login(request): if request.method == 'POST': if request.session.test_cookie_worked(): request.session.delete_test_cookie() return HttpResponse("You're logged in.") else: return HttpResponse("Please enable cookies and try request.session.set_test_cookie() return render_to_response('foo/login_form.html') Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 19 / 34
Atrybuty ciasteczek max_age czas wa»no±ci w sekundach expires data wa»no±ci w formacie "Wdy, DD-Mth-YY HH:MM:SS GMT" path ±cie»ka domain domena wa»no±ci np..mimuw.edu.pl secure czy wolno przekazywa ciastko tylko po HTTPS Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 20 / 34
Sesje # Ustawianie: request.session["fav_color"] = "blue" # Odczyt fav_color = request.session["fav_color"] # Kasowanie del request.session["fav_color"] # Sprawdzanie if "fav_color" in request.session:... Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 21 / 34
Jak dziaªaj sesje S cz ±ci aplikacji django.contrib.sessions S zapisywane w bazie danych >>> from django.contrib.sessions.models import Session >>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceea >>> s.expire_date datetime.datetime(2005, 8, 20, 13, 35, 12) Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 22 / 34
Kiedy sesje s modykowane # Sesja jest modyfikowana request.session['foo'] = 'bar' # Sesja jest modyfikowana del request.session['foo'] # Sesja jest modyfikowana request.session['foo'] = {} # Sesja NIE jest modyfikowana bo zmienia si # request.session['foo'] a nie request.session. request.session['foo']['bar'] = 'baz' Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 23 / 34
Techniczne szczegóªy W sesji mo»na zapisa wszystko, co da si zapicklowa. Sesje przechowywane s w tabeli django_session. Dane odczytywane s na» danie Ciasteczko jest ustawiane tylko w przypadku takiej konieczno±ci. Sesje s oparte w caªo±ci na ciasteczkach, w przeciwie«stwie do PHP i JSP. Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 24 / 34
U»ytkownicy Users u»ytkownicy strony Permissions logiczne (tak/nie) uprawnienia do poszczególnych czynno±ci Groups nadawanie uprawnie«caªej grupie osób Messages wiadomo±ci dla u»ytkowników Proles rozszerzanie obiektów opisuj cych u»ytkowników Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 25 / 34
Jak dziaªaja mechanizm uprawnie«aplikacja django.contrib.auth if request.user.is_authenticated(): # Do something for authenticated users. else: # Do something for anonymous users. Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 26 / 34
U»ytkownik 1 username nazwa 30 znaków rst_name, last_name opcjonalne 30 znaków Email opcjonalny Password wymagane, przechowywany hash is_sta dost p do admin is_active aktywny, czy mo»e si logowa is_superuser ma wszystkie uprawnienia last_login kiedy si logowaª date_joined kiedy zaªo»one konto Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 27 / 34
U»ytkownik 2 is_authenticated() czy si zalogowaª is_anonymous() czy nie jest anonimowy get_full_name() imie, spacja, nazwisko set_password(passwd) ustawia hasªo check_password(passwd) sprawdza get_group_permissions() uprawnienia wynikaj ce z grup get_all_permissions() wszystkie uprawnienia. has_perm(perm) sprawdza uprawnienie Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 28 / 34
U»ytkownik 3 has_perms(perm_list) sprawdza wszystkie uprawnienia has_module_perms(app_label) sprawdza jakiekolwiek uprawnienie w aplikacji get_and_delete_messages() wiadomo±ci dla u»ytkownika email_user(subj, msg) wysyªa email get_prole() dodatkowe pola Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 29 / 34
Grupy i uprawnienia myuser.groups = group_list # ustawia myuser.groups.add(group1, group2,...) # dodaje myuser.groups.remove(group1, group2,...) # usuwa myuser.groups.clear() # usuwa z wszystkich grup # Uprawnienia podobnie myuser.permissions = permission_list myuser.permissions.add(permission1, permission2,...) myuser.permissions.remove(permission1, permission2,...) myuser.permissions.clear() Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 30 / 34
Logowanie from django.contrib import auth def login(request): username = request.post['username'] password = request.post['password'] user = auth.authenticate(username=username, password=password) if user is not None and user.is_active: auth.login(request, user) return HttpResponseRedirect("/account/loggedin/") else: return HttpResponseRedirect("/account/invalid/") Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 31 / 34
Wylogowanie from django.contrib import auth def logout(request): auth.logout(request) return HttpResponseRedirect("/account/loggedout/") Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 32 / 34
Szablon logowania {% block content %} {% if form.errors %} <p class="error">sorry, that's not a valid username or password</p> {% endif %} <form action='.' method='post'> <label for="username">user name:</label> <input type="text" name="username" value="" id="username"> <label for="password">password:</label> <input type="password" name="password" value="" id="password"> <input type="submit" value="login" /> <input type="hidden" name="next" value="{{ next escape }}" /> Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 33 / 34
Co z niezalogowanym from django.http import HttpResponseRedirect def my_view(request): if not request.user.is_authenticated(): return HttpResponseRedirect('/login/?next=%s' % request.path) #... ==== from django.contrib.auth.decorators import login_required @login_required def my_view(request): #... Krzysztof Ciebiera () Serwer WWW na przykªadzie Django cz.3 20 kwietnia 2010 34 / 34