Web осень 2012 лекция 7

41
Django. Часть 2 Александр Бекбулатов

Transcript of Web осень 2012 лекция 7

Page 1: Web осень 2012 лекция 7

Django. Часть 2

Александр Бекбулатов

Page 2: Web осень 2012 лекция 7

Что изучили

• MVC. Архитектура Django

• Модели

• Контроллеры

• Роутинг

• Шаблоны

Page 3: Web осень 2012 лекция 7

Что будем изучать

• Формы

• Теги и фильтры в шаблонах

• Class Based Views

• Панель администрирования

• Middleware

• Кеширование

• Производительность

Page 4: Web осень 2012 лекция 7
Page 5: Web осень 2012 лекция 7

Формы

vim blog/forms.py

from django import forms

class ContactForm(forms.Form): email = forms.EmailField(label=u'Ваш e-mail', max_length=100) message = forms.CharField(label=u'Сообщение', widget=forms.Textarea)

Page 6: Web осень 2012 лекция 7

Формы

Список полей

BooleanField, CharField, ChoiceField, TypedChoiceField,

DateField, DateTimeField, DecimalField, EmailField,

FileField, FilePathField, FloatField, ImageField, IntegerField,

IPAddressField, GenericIPAddressField, MultipleChoiceField,

TypedMultipleChoiceField, NullBooleanField, RegexField,

SlugField, TimeField, URLField, ComboField, MultiValueField,

SplitDateTimeField, ModelChoiceField,

ModelMultipleChoiceField

Page 7: Web осень 2012 лекция 7

Формы

API

>>> f = ContactForm()>>> data = {'email': '[email protected]', 'message': 'Hi there’}>>> f = ContactForm(data)>>> f.is_valid()True>>> f.cleaned_data {'email': u'[email protected]', 'message': u'Hi there’}>>> f = ContactForm({})>>> f.is_valid()False>>> f.errors{'email': [u'Enter a valid e-mail address.'], 'message': [u'This field is required.']}>>> f = ContactForm()>>> print f.as_table()<tr><th><label for="id_for_email">Ваш e-mail:</label></th><td><input id="id_for_ email " type="text" name="email" maxlength="100" /></td></tr>…

Page 8: Web осень 2012 лекция 7

Формы

vim blog/views.pyfrom blog.forms import ContactFormfrom django.core.mail import send_mailfrom django.http import HttpResponseRedirect

def contact(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): subject = u'Сообщение с блога' message = form.cleaned_data['message'] sender = form.cleaned_data['email'] recipients = ['[email protected]'] send_mail(subject, message, sender, recipients) return HttpResponseRedirect('/') else: form = ContactForm()

return render(request, 'blog/contact.html', { 'form': form })

Page 9: Web осень 2012 лекция 7

Формы

vim templates/blog/contact.html

{% extends "base.html" %}{% block content %} <form action="" method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="Отправить" /> </form>{% endblock %}

Page 10: Web осень 2012 лекция 7

Формы

from django import forms

class PostForm(forms.ModelForm):

class Meta: model = Article fields = ('title', 'content', 'category')

Page 11: Web осень 2012 лекция 7

Шаблоны

Page 12: Web осень 2012 лекция 7

Шаблоны

RequestContext и Context

TEMPLATE_CONTEXT_PROCESSORS:

• django.contrib.auth.context_processors.auth (user, perms)

• django.core.context_processors.csrf (csrf_token)

• django.core.context_processors.request (request)

• django.core.context_processors.static (STATIC_URL)

• …

Page 13: Web осень 2012 лекция 7

Шаблоны

vim blog/templatetags/blog_tags.py

from django import templatefrom blog.models import Post

register = template.Library()

@register.inclusion_tag('blog/tags/last_posts.html')def last_posts():    return {'post_list': Post.objects.all()[:5]}

Page 14: Web осень 2012 лекция 7

Шаблоны

vim templates/blog/tags/last_posts.html

<ul>{% for object in post_list %} <li><a href="{{ object.get_absolute_url}}">{{ object }}</a></li>{% endfor %}</ul>

Подключение

{% load blog_tags %}

{% last_posts %}

Page 15: Web осень 2012 лекция 7

Контроллеры CBV

• TemplateView

• RedirectView

• ListView

• DetailView

• FormView

• CreateView

• UpdateView

• DeleteView

• ArchiveIndexView

• YearArchiveView

• …

Page 16: Web осень 2012 лекция 7

Контроллеры CBV

Контроллер-функция (пример 1)

def post_detail(request, pk): try: object = Post.objects.get(pk=pk) except Post.DoesNotExist: raise Http404 return render( request, 'blog/post_detail.html', {'object': object} )

urlpatterns = patterns('', url(r'^post/(?P<pk>\d+)/$', post_detail, name='post_detail'),)

Page 17: Web осень 2012 лекция 7

Контроллеры CBV

Контроллер-класс (пример 1)

class PostDetail(generic.DetailView): model=Post 

urlpatterns = patterns('', url(r'^post/(?P<pk>\d+)/$', PostDetail.as_view(), name='post_detail'),)

Page 18: Web осень 2012 лекция 7

Контроллеры CBV

Контроллер-функция (пример 2)

def post_list(request): paginator = Paginator(Post.objects.all(), 25)  page = request.GET.get('page') try: posts = paginator.page(page) except PageNotAnInteger: posts = paginator.page(1) except EmptyPage: posts = paginator.page(paginator.num_pages) return render( request, 'blog/post_list.html', {'object_list': posts} )

Page 19: Web осень 2012 лекция 7

Контроллеры CBV

Контроллер-класс (пример 2)

class PostList(generic.ListView): model = Post paginate_by = 25

Page 20: Web осень 2012 лекция 7

Контроллеры CBV

Контроллер-функция (пример 3)

@login_requireddef category(request, pk): cat = get_object_or_404(Category, pk=pk) post_list = Post.objects.filter(category=cat) return render(request, 'blog/category.html', { 'category': cat, 'post_list' : post_list })

Page 21: Web осень 2012 лекция 7

Контроллеры CBV

Контроллер-класс (пример 3)

class CategoryListView(generic.ListView): template_name = 'blog/category.html'  def get_queryset(self): self.cat = get_object_or_404(Category, pk=self.kwargs['pk']) return Post.objects.filter(category=self.cat)  @method_decorator(login_required) def dispatch(self, *args, **kwargs): return super(CategoryListView, self).dispatch(*args, **kwargs)  def get_context_data(self, **kwargs): context = super(CategoryListView, self).get_context_data(**kwargs) context['category'] = self.cat return context

Page 22: Web осень 2012 лекция 7

Контроллеры CBV

http://ccbv.co.uk/

Page 23: Web осень 2012 лекция 7

Панель администрирования

vim myblog/urls.py

from django.conf.urls import patterns, include, url # Uncomment the next two lines to enable the admin:from django.contrib import adminadmin.autodiscover() urlpatterns = patterns('',  … # Uncomment the next line to enable the admin: url(r'^admin/', include(admin.site.urls)),)

Page 24: Web осень 2012 лекция 7

Панель администрирования

vim blog/admin.py

from blog.models import Category, Postfrom django.contrib import admin

class PostAdmin(admin.ModelAdmin): date_hierarchy = 'creation_date' list_display = ('title', 'category') list_filter = ('category',)  search_fields = ('title',)

admin.site.register(Category)admin.site.register(Post, PostAdmin)

Page 25: Web осень 2012 лекция 7

Панель администрирования

Page 26: Web осень 2012 лекция 7

Панель администрирования

Page 27: Web осень 2012 лекция 7

Панель администрирования

Page 28: Web осень 2012 лекция 7

Панель администрирования

Page 29: Web осень 2012 лекция 7

Middleware

Page 30: Web осень 2012 лекция 7

Middleware

Методы

• process_request(self, request)

• process_view(self, request, view_func, view_args,

view_kwargs)

• process_template_response(self, request,

response)

• process_response(self, request, response)

• process_exception(self, request, exception)

Page 31: Web осень 2012 лекция 7

Middleware

Примеры

• Обработка запроса

• Статистика

• Аутентификация

• Защита от CSRF

• Редиректы

• Кеширование

Page 32: Web осень 2012 лекция 7

Кеширование

Схема кеширования

Ищем значение в кеше

Если находим:

• возвращаем значение из кеша

Если нет:

• генерируем значение

• сохраняем в кеш

• возвращаем значение

Page 33: Web осень 2012 лекция 7

Кеширование

Условия кеширования

• Быстрый доступ к кешу

• Высокая вероятность использования кеша

• Временное хранилище

Page 34: Web осень 2012 лекция 7

Кеширование в Django

Поддержка

• Memcached

• База данных

• Файловая система

• Локальная память

• Dummy (для разработки)

Page 35: Web осень 2012 лекция 7

Кеширование в Django

Уровни кеширования

• Весь сайт

• Контроллер

• Часть шаблона

• Часть данных (ручное управление)

Page 36: Web осень 2012 лекция 7

Кеширование в Django

Ключ кеша

• Префикс

• Версия

• Ключ записи

Page 37: Web осень 2012 лекция 7

Кеширование в Django

Инвалидация кеша

• По таймауту

• По событию

Page 38: Web осень 2012 лекция 7

Производительность Django

Premature optimization is the root of all evil in programming.

• Оптимизация запросов к базе данных

• Кеширование данных

• Кеширование шаблонов

Page 39: Web осень 2012 лекция 7

Производительность Django

• Профилируйте запросы с Django Debug Toolbar

• Используйте правильные индексы (db_index)

• Делайте выборки по тем полям, которые вам

нужны (методы only, values and values_list)

• Не делайте лишних запросов к БД (методы

select_related и prefetch_related, тег {% with

%}, внешние ключи)

• Python не должен делать работу за БД

(методы count, exist)

Page 40: Web осень 2012 лекция 7

Полезные ссылки

• https://docs.djangoproject.com/en/1.4/

• http://django.me/render

• https://github.com/django/django

• http://www.djangosites.org/with-source/

• http://stackoverflow.com/

Page 41: Web осень 2012 лекция 7

Спасибо за вниманиеБекбулатов Александр

e-mail: [email protected]