django (web konferencia 2009)
TRANSCRIPT
Farkas SzilveszterMagyarországi Web KonferenciaBudapest, 2009. október 3.
Farkas Szilveszter
Farkas Szilveszter
Farkas Szilveszter
Farkas Szilveszter
from presentation import (Django, Forms, Middleware, Tests, Python)
>>> import django
>>> django.ORIGINAL_AUTHOR'Adrian Holovaty'
>>> django.OPEN_SOURCEDdatetime.date(2005, 7, 13)
>>> django.VERSION'1.1-final'
>>> len(django.AUTHORS)485
>>> import django
>>> django.ORIGINAL_AUTHOR'Adrian Holovaty'
>>> django.OPEN_SOURCEDdatetime.date(2005, 7, 13)
>>> django.VERSION'1.1-final'
>>> len(django.AUTHORS)485
>>> import django
>>> django.ORIGINAL_AUTHOR'Adrian Holovaty'
>>> django.OPEN_SOURCEDdatetime.date(2005, 7, 13)
>>> django.VERSION'1.1-final'
>>> len(django.AUTHORS)485
>>> import django
>>> django.ORIGINAL_AUTHOR'Adrian Holovaty'
>>> django.OPEN_SOURCEDdatetime.date(2005, 7, 13)
>>> django.VERSION'1.1-final'
>>> len(django.AUTHORS)485
>>> import django
>>> django.ORIGINAL_AUTHOR'Adrian Holovaty'
>>> django.OPEN_SOURCEDdatetime.date(2005, 7, 13)
>>> django.VERSION'1.1-final'
>>> len(django.AUTHORS)485
>>> django.MODEL'model'
>>> django.VIEW'template'
>>> django.CONTROLLER'view'
$ django-admin startproject webkonf
$ cd webkonf
$ ./manage.py startapp conference
from django.db import models
class Venue(models.Model): name = models.CharField(max_length=64) address = models.CharField(max_length=128)
class Conference(models.Model): name = models.CharField(max_length=32) venue = models.ForeignKey(ConferenceVenue)
from django.contrib.auth.models import User
class Attendee(models.Model): user = models.OneToOneField(User) conferences = models.ManyToManyField( Conference, related_name='attendees')
from django.db import models
class Venue(models.Model): name = models.CharField(max_length=64) address = models.CharField(max_length=128)
class Conference(models.Model): name = models.CharField(max_length=32) venue = models.ForeignKey(Venue)
from django.contrib.auth.models import User
class Attendee(models.Model): user = models.OneToOneField(User) conferences = models.ManyToManyField( Conference, related_name='attendees')
from django.db import models
class Venue(models.Model): name = models.CharField(max_length=64) address = models.CharField(max_length=128)
class Conference(models.Model): name = models.CharField(max_length=32) venue = models.ForeignKey(Venue)
from django.contrib.auth.models import User
class Attendee(models.Model): user = models.OneToOneField(User) conferences = models.ManyToManyField( Conference, related_name='attendees')
[...]<h1>{{ conference.name }}</h1>
<h2>Látogatók</h2>
<ul>{% for attendee in conference.attendees.all %} <li>{{ attendee.user.get_full_name }}</li>{% endfor %}</ul>[...]
from django.shortcuts import (get_object_or_404, render_to_response)from conference.models import Conference
def conference_page(request, conf_id): conference = get_object_or_404( Conference, pk=conf_id) context = { 'conference': conference } return render_to_response( 'conference.html', context)
from django.conf.urls.defaults import *
urlpatterns = patterns('', (r'^/conf/(?P<conf_id>\d+)/$', 'conference.views.conference_page'),)
from django import forms
űrlapok
űrlapok
szerver oldali adatellenőrzés
Űrlap osztály
class AttendeeForm(forms.Form):
Mező
name = forms.CharField('Név', max_length=32)
Widget
password = forms.CharField( 'Jelszó', max_length=32, widget=forms.PasswordInput())
Űrlap osztály
class AttendeeForm(forms.Form):
Mező
name = forms.CharField('Név', max_length=32)
Widget
password = forms.CharField( 'Jelszó', max_length=32, widget=forms.PasswordInput())
Űrlap osztály
class AttendeeForm(forms.Form):
Mező
name = forms.CharField('Név', max_length=32)
Widget
password = forms.CharField( 'Jelszó', max_length=32, widget=forms.PasswordInput())
Beépített ellenőrzés
email = forms.EmailField(max_length=75)zip = forms.IntegerField(min_value=1000, max_value=9999)
Mezőszintű egyedi ellenőrzés
def clean_FIELDNAME(self):
Űrlapszintű egyedi ellenőrzés
def clean(self):
Beépített ellenőrzés
email = forms.EmailField(max_length=75)zip = forms.IntegerField(min_value=1000, max_value=9999)
Mezőszintű egyedi ellenőrzés
def clean_FIELDNAME(self):
Űrlapszintű egyedi ellenőrzés
def clean(self):
Beépített ellenőrzés
email = forms.EmailField(max_length=75)zip = forms.IntegerField(min_value=1000, max_value=9999)
Mezőszintű egyedi ellenőrzés
def clean_FIELDNAME(self):
Űrlapszintű egyedi ellenőrzés
def clean(self):
Mezőszintű egyedi ellenőrzés
def clean_email(self): if 'email' in self.cleaned_data: email = self.cleaned_data['email'] if not email.endswith('@web.conf.hu'): raise forms.ValidationError('Nem vagy szervező.') else: return email
from django import middlewares
process_request()
process_view()
process_response()
process_exception()
from django.http import HttpResponseRedirect
class LoginMiddleware(object): def process_request(self, request): if not request.user.is_authenticated(): if request.get_full_path() != '/login/': return HttpResponseRedirect( '/login/?next=%s' % request.get_full_path()) else: return None
from django.http import HttpResponseRedirect
class LoginMiddleware(object): def process_request(self, request): if not request.user.is_authenticated(): if request.get_full_path() != '/login/': return HttpResponseRedirect( '/login/?next=%s' % request.get_full_path()) else: return None
process_view(self, request, view_func, view_args, view_kwargs)
process_response(self, request, response)
process_exception(self, request, exception)
from django import test
doctest
class Conference(models.Model): """ >>> v = Venue.objects.create( name='CEU', address='Budapest') >>> c = Conference.objects.create( Name='WebKonf', venue=v) >>> c.name u'WebKonf' >>> c.venue.name u'CEU' """ name = models.CharField(max_length=32) venue = models.ForeignKey(Venue)
unittest
import unittest
class ConferenceTest(unittest.TestCase): def setUp(self): venue = Venue.objects.create( Name='CEU', address='Budapest') self.conf = Conference.objects.create( Name='WebKonf', venue=venue)
def test_conference(self): self.assertEquals(self.conf.name, u'WebKonf') self.assertEquals(self.conf.venue.name, u'CEU')
def tearDown(self): self.conf.delete()
from django.test import TestCase
-> kliens (GET, POST)
-> „hozzávalók” beemelése (JSON/XML dump)
-> egyedi url konfiguráció
-> e-mail fiók
-> további assert-ek
from django.test import TestCase
-> kliens (GET, POST)
def test_conference(self): response = self.client.get('/conf/1/') self.assertTrue('<h1>WebKonf</h1>' in response.content)
from django.test import TestCase
-> „hozzávalók” beemelése (JSON/XML dump)
class ConferenceTest(TestCase): fixtures = ['webkonf.json']
$ ./manage.py dumpdata conference > \conference/fixtures/webkonf.json
from django.test import TestCase
-> egyedi url konfiguráció
class ConferenceTest(TestCase): urls = 'conference.test_urls'
from django.test import TestCase
-> e-mail fiók
from django.core import maildef test_email(self): mail.send_mail('Subject', 'Message.', '[email protected]', ['[email protected]'], fail_silently=False)
self.assertEquals(len(mail.outbox), 1)
self.assertEquals(mail.outbox[0].subject, 'Subject')
from django.test import TestCase
-> további assert-ek
assertContains(response, text, count=None, status_code=200)
assertNotContains(response, text, status_code=200)
assertFormError(response, form, field, errors)
assertTemplateUsed(response, template_name)
assertTemplateNotUsed(response, template_name)
assertRedirects(response, expected_url, status_code=302, target_status_code=200)
$ python
from django.db import modelsfrom django.contrib.localflavor.us.models import USStateField
class Venue(models.Model): name = models.CharField(max_length=64) address = models.CharField(max_length=128)
class USVenue(Venue): state = USStateField(default='CA')
class ConferenceVenue(Venue): rooms = forms.PositiveIntegerField()
from django.db import modelsfrom django.contrib.localflavor.us.models import USStateField
class Venue(models.Model): name = models.CharField(max_length=64) address = models.CharField(max_length=128)
class USVenue(Venue): state = USStateField(default='CA')
class ConferenceVenue(Venue): rooms = forms.PositiveIntegerField()
from django.db import modelsfrom django.contrib.localflavor.us.models import USStateField
class Venue(models.Model): name = models.CharField(max_length=64) address = models.CharField(max_length=128)
class USVenue(Venue): state = USStateField(default='CA')
class ConferenceVenue(Venue): rooms = forms.PositiveIntegerField()
from django.db import modelsfrom django.contrib.localflavor.us.models import USStateField
class Venue(models.Model): name = models.CharField(max_length=64) address = models.CharField(max_length=128)
class Meta: abstract = True
class USVenue(Venue): state = USStateField(default='CA')
class ConferenceVenue(Venue): rooms = forms.PositiveIntegerField()
from django.contrib.auth.decorators import login_required
@login_requireddef conference_private(request):[...]
from django.utils.decorators import decorator_from_middlewarefrom conference.middleware.login import LoginMiddleware
login_required = decorator_from_middleware( LoginMiddleware)
@login_requireddef conference_private(request):[...]
from django.contrib.auth.decorators import login_required
@login_requireddef conference_private(request):[...]
from django.utils.decorators import decorator_from_middlewarefrom conference.middleware.login import LoginMiddleware
login_required = decorator_from_middleware( LoginMiddleware)
@login_requireddef conference_private(request):[...]
Modulok (csomagok)
__init__.pyconference/ __init__.py models.py templates/ conference.html views.pymanage.pysettings.pyurls.py
Modulok (csomagok)
__init__.pyconference/ __init__.py models.py templates/ conference.html views.pymanage.pyregistration/ [...]settings.pyurls.py
Modulok (csomagok)
__init__.pyconference/ __init__.py models.py templates/ conference.html views/ __init__.py attendees.py conferences.pymanage.pyregistration/ [...]settings.pyurls.py
Globális/újrahasznosítható modulok
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'conference',)
Globális/újrahasznosítható modulok
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'conference', 'django_registration',)
Globális/újrahasznosítható modulok
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'conference', 'django_registration', 'django_openid_auth',)
Globális/újrahasznosítható modulok
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'conference', 'django_registration', 'django_openid_auth', 'django_contact_form',)
from django.conf.urls.defaults import *
urlpatterns = patterns('', (r'^/conf/(?P<conf_id>\d+)/$', 'conference.views.conference_page'), (r'^openid/', include('django_openid_auth.urls')),)
Globális/újrahasznosítható modulok
django-compressordjango-contact-formdjango-db-logdjango-debug-toolbardjango-extensionsdjango-flatblocksdjango-gravatardjango-oembeddjango-openid-authdjango-proxydjango-registrationdjango-taggingdjango-timezonesdjango-tinymcedjango-votingdjango-wikiapp
Remixek
Pinax(http://pinaxproject.com/)
37 django-*
Mingus(http://github.com/montylounge/django-mingus/)
28 django-*
Hivatkozások
http://www.djangoproject.com/
http://docs.djangoproject.com/
http://gábor.20y.hu/django/