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

Post on 19-May-2015

90 views 3 download

Tags:

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

Django. Часть 2

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

Что изучили

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

• Модели

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

• Роутинг

• Шаблоны

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

• Формы

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

• Class Based Views

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

• Middleware

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

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

Формы

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)

Формы

Список полей

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

Формы

API

>>> f = ContactForm()>>> data = {'email': 'foo@example.com', 'message': 'Hi there’}>>> f = ContactForm(data)>>> f.is_valid()True>>> f.cleaned_data {'email': u'foo@example.com', '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>…

Формы

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 = ['a.bekbulatov@corp.mail.ru'] send_mail(subject, message, sender, recipients) return HttpResponseRedirect('/') else: form = ContactForm()

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

Формы

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 %}

Формы

from django import forms

class PostForm(forms.ModelForm):

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

Шаблоны

Шаблоны

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)

• …

Шаблоны

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]}

Шаблоны

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 %}

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

• TemplateView

• RedirectView

• ListView

• DetailView

• FormView

• CreateView

• UpdateView

• DeleteView

• ArchiveIndexView

• YearArchiveView

• …

Контроллеры 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'),)

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

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

class PostDetail(generic.DetailView): model=Post 

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

Контроллеры 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} )

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

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

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

Контроллеры 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 })

Контроллеры 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

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

http://ccbv.co.uk/

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

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)),)

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

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)

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

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

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

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

Middleware

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)

Middleware

Примеры

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

• Статистика

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

• Защита от CSRF

• Редиректы

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

Кеширование

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

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

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

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

Если нет:

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

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

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

Кеширование

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

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

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

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

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

Поддержка

• Memcached

• База данных

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

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

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

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

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

• Весь сайт

• Контроллер

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

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

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

Ключ кеша

• Префикс

• Версия

• Ключ записи

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

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

• По таймауту

• По событию

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

Premature optimization is the root of all evil in programming.

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

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

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

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

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

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

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

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

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

select_related и prefetch_related, тег {% with

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

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

(методы count, exist)

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

• 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/

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

e-mail: a.bekbulatov@corp.mail.ru