Serwer WWW na przykªadzie Django cz.1 Krzysztof Ciebiera 13 marca 2014 Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 1 / 37
1 Historia CGI PHP klasyczne 2 Wzorzec MVC Intuicja Przykªad 3 Django 4 Szablony Filrty Tagi Wªasne rozszerzenia Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 2 / 37
Wady podej±cia import MySQLdb print "Content-Type: text/html" print print "<html><head><title>books</title></head>" print "<body>" print "<h1>books</h1>" print "<ul>" connection = MySQLdb.connect( user='me', passwd='letmein', db='my_db') cursor = connection.cursor() cursor.execute("select name FROM books ORDER BY pub_date DESC LIMIT 10") for row in cursor.fetchall(): print "<li>%s</li>" % row[0] print "</ul></body></html>" connection.close() Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 3 / 37
Wady podej±cia Dlaczego musimy si ª czy w ten sposób z baz danych? Czy sami powinni±my pami ta o Content-Type i zamkni ciu bazy danych? Jak u»ywa tego samego kodu w ró»nych konguracjach? Co ma robi projektant stron, nie znaj cy pythona? Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 4 / 37
PHP "gg:mysql php example" $chandle = mysql_pconnect("localhost", $username, $password) or die("connection Failure to Database"); session_register("database"); $database=$query_string; mysql_select_db($database, $chandle) or die ("Database not found."); $tablelist=mysql_list_tables($database); echo "<H3>Available Tables in the ", $database, " Database:</ echo "<UL>"; $table = 0; while ($table < mysql_num_rows($tablelist)) {...$... Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 5 / 37
Filozoa Model Zawiera opis danych (baza danych) Widok Logika wy±wietlania Mapowanie Który url uruchamia któr funkcj widoku (odpowiednik kontrolera) Szablon Opisuje jak to wy±wietla Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 6 / 37
Model # models.py (the database tables) from django.db import models class Book(models.Model): name = models.charfield(maxlength=50) pub_date = models.datefield() Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 7 / 37
Widok # views.py (the business logic) from django.shortcuts import render_to_response from models import Book def latest_books(request): book_list = Book.objects.order_by('-pub_date')[:10] return render_to_response('latest_books.html', {'book_list': book_list}) Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 8 / 37
Mapowanie # urls.py (the URL configuration) from django.conf.urls.defaults import * import views urlpatterns = patterns('', (r'latest/$', views.latest_books), ) Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 9 / 37
Szablon # latest_books.html (the template) <html><head><title>books</title></head> <body> <h1>books</h1> <ul> {% for book in book_list %} <li>{{ book.name }}</li> {% endfor %} </ul> </body></html> Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 10 / 37
Jak uruchomi Django? Potrzebny jest python Virtualenv instalacja django, South, django-debug-toolbar django-admin.py startproject mysite mysite/manage.py mysite/mysite/ init.py mysite/mysite/settings.py mysite/mysite/urls.py mysite/mysite/wsgi.py python manage.py runserver 127.0.0.1:8080 (lokalnie) python manage.py runserver 0.0.0.0:8080 (publicznie) Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 11 / 37
Najprostsza aplikacja from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>it is now %s.</body></html>" % now return HttpResponse(html) Ale sk d system wie,»e t funkcj nale»y uruchomi? Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 12 / 37
Mapowanie aplikacji from django.conf.urls.defaults import * from mysite.views import current_datetime urlpatterns = patterns('', (r'^time/$', current_datetime), ) Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 13 / 37
Wyra»enia regularne. (kropka) cokolwiek \d cyfra [A Z] wielka litera [a z] maªa litera [A Za z] jakakolwiek litera + jeden lub wi cej * zero lub wi cej 1,3 mi dzy jeden a trzy Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 14 / 37
Jak to dziaªa technicznie Django importuje settings.py Ustawia ROOT_URLCONF UrlConf odpowiada za przekazanie» dania do widoku (mamy sªabe wi zania) Widok odpowiada za zwrócenie HttpResponse Naprawd to jest odrobink bardziej skomplikowane Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 15 / 37
Dynamiczne URL mapowanie from django.conf.urls.defaults import * from mysite.views import current_datetime, hours_ahead urlpatterns = patterns('', (r'^time/$', current_datetime), (r'^time/plus/(\d{1,2})/$', hours_ahead), ) Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 16 / 37
Dynamiczne URL obsªuga def hours_ahead(request, offset): offset = int(offset) dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html = "<html><body>in %s hour(s), it will be %s.</body></html>" % (offset, dt) return HttpResponse(html) Komunikaty o bª dach s sensowne. Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 17 / 37
Szablony 1 <html> <head><title>ordering notice</title></head> <body> <p>dear {{ person_name }},</p> <p>thanks for placing an order from {{ company }}. It's scheduled to ship on {{ ship_date date:"f j, Y" }}.</p> <p>here are the items you've ordered:</p> <ul> {% for item in item_list %} <li>{{ item }}</li> {% endfor %} </ul> Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 18 / 37
Szablony 2 {% if ordered_warranty %} <p>your warranty information will be included in the packaging.</p> {% endif %} <p>sincerely,<br />{{ company }}</p> </body> </html> Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 19 / 37
Szablony 3 >>> from django.template import Context, Template >>> t = Template("My name is {{ name }}.") >>> c = Context({"name": "Stephane"}) >>> t.render(c) 'My name is Stephane.' Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 20 / 37
Szablony 4 >>> from django.template import Template, Context >>> t = Template('Hello, {{ name }}') >>> print t.render(context({'name': 'John'})) Hello, John >>> print t.render(context({'name': 'Julie'})) Hello, Julie >>> print t.render(context({'name': 'Pat'})) Hello, Pat Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 21 / 37
Filtry (cz ± ) {{ name lower }} {{ my_text escape linebreaks }} {{ bio truncatewords:"30" }} {{ pub_date date:"f j, Y" }} {{ value cut:" " }} {{ value default:"nothing" }} {{ value default_if_none:"nothing" }} {{ value dictsort:"name" }} {{ value floatformat:3 }} 34.230 {{ value urlize }} {{ value yesno:"yeah,no,maybe" }} Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 22 / 37
Tag if w szablonie {% if today_is_weekend %} <p>welcome to the weekend! {% else %} <p>get back to work.</p> {% endif %} mo»na u»y and, or, not pusta lista ([]), tupla (()), sªownik ({}), string (), zero (0), i None s False nie ma nawiasów i ª czenia or i and Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 23 / 37
Tag for w szablonie {% for country in countries %} <h1>{{ country.name }}</h1> <ul> {% for city in country.city_list %} <li>{{ city }}</li> {% endfor %} </ul> {% endfor %} Z fora nie mo»na wyskoczy Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 24 / 37
W tagu for s dost pne forloop.counter licznik forloop.counter0 licznik o bazie 0 forloop.revcounter licznik odwrotny forloop.revcounter0 licznik odwrotny o bazie 0 forloop.rst czy pierwszy forloop.last czy ostatni forloop.parentloop referencja do wy»szego forloopa Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 25 / 37
Inne rzeczy {% ifequal variable 1 %} {% ifequal variable 1.23 %} {% ifnequal variable 'foo' %} {% ifnequal variable "foo" %} {# This is a comment #} Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 26 / 37
Escape {% autoescape on %} {{ body }} {% endautoescape %} {% load cycle from future %} % for o in some_list %} <tr class="{% autoescape off %} {% cycle rowvalue1 rowvalue2 %} {% endautoescape %}">... </tr> {% endfor %} Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 27 / 37
Regroup cities = [{'name': 'Mumbai', 'population': '19,000,000', 'count {'name': 'Calcutta', 'population': '15,000,000', 'country': {'name': 'New York', 'population': '20,000,000', 'country': {'name': 'Chicago', 'population': '7,000,000', 'country': ' {'name': 'Tokyo', 'population': '33,000,000', 'country': 'J {% regroup cities by country as country_list %} <ul>{% for country in country_list %} <li>{{ country.grouper }} <ul> {% for item in country.list %} <li>{{ item.name }}: {{ item.population }}</li> {% endfor %} </ul> </li> {% endfor %}</ul> Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 28 / 37
URL {% url 'path.to.some_view' v1 v2 %} {% url 'path.to.some_view' arg1=v1 arg2=v2 %} url: ('^client/(\d+)/$', 'app_views.client') szablon: {% url 'app_views.client' client.id %} Przerwa Dok d to zmierza? Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 29 / 37
Load polls/ models.py templatetags/ init.py poll_extras.py views.py poll_extras.py: from django import template register = template.library() W szablonie: {% load poll_extras %} Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 30 / 37
Wªasny ltr W szablonie {{ somevariable cut:"0" }} ====== def cut(value, arg): """Removes all values of arg from the given string""" return value.replace(arg, '') register.filter('cut', cut) === albo === @register.filter def cut(value, arg): return value.replace(arg, '') Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 31 / 37
Wªasny tag 1 <p>the time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p> ====== def do_current_time(parser, token): try: # split_contents() knows not to split quoted strings. tag_name, format_string = token.split_contents() except ValueError: raise template.templatesyntaxerror("%r \ tag requires a single argument" % \ token.contents.split()[0]) if not (format_string[0] == format_string[-1] \ and format_string[0] in ('"', "'")): raise template.templatesyntaxerror( "%r tag's argument should be in quotes" % tag_name) return CurrentTimeNode(format_string[1:-1]) Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 32 / 37
Wªasny tag 2 <p>the time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p> ====== class CurrentTimeNode(template.Node): def init (self, format_string): self.format_string = format_string def render(self, context): return datetime.datetime.now().strftime(self.format_string) ===== register.tag('current_time', do_current_time) Dlaczego tak? Podziaª na kompilacj i wykonanie ma na celu przyspieszenie systemu. Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 33 / 37
Wªasny tag 3 W tki Tagi: proste, przypisa«, bloków django/template/defaulttags.py Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 34 / 37
Dziedziczenie szablonów 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="en"> <head><title>{% block title %}{% endblock %}</title></head> <body> <h1>my helpful timestamp site</h1> {% block content %}{% endblock %} {% block footer %} <hr> <p>thanks for visiting my site.</p> {% endblock %} </body> </html> Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 35 / 37
Dziedziczenie szablonów 2 {% extends "base.html" %} {% block title %}The current time{% endblock %} {% block content %} <p>it is now {{ current_date }}.</p> {% endblock %} {% extends "base.html" %} {% block title %}Future time{% endblock %} {% block content %} <p>in {{ hour_offset }} hour(s), it will be {{ next_time }}.</p> {% endblock %} </html> Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 36 / 37
Szablony staticles {% load staticfiles %} <link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" /> collectstatic django-admin.py collectstatic Zbiera wszystkie pliki statyczne projektu do STATIC_ROOT. Pliki mog by serwowane przez zewn trzny serwer. Krzysztof Ciebiera Serwer WWW na przykªadzie Django cz.1 13 marca 2014 37 / 37