Владимир Филонов -...

103
Будничный Django Владимир Филонов

Transcript of Владимир Филонов -...

Page 1: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Владимир Филонов

Page 2: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Программируем8-14 часов в день

Page 3: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

8-14 часов в деньПочти каждый день

Page 4: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

≈3000 часов в год

Будничный Django

Page 5: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Как проходит это время?

Будничный Django

Page 6: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

≈30% мы творим

Page 7: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

50-70% - рутина

Page 8: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Как же так жить?

Будничный Django

Page 9: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Задачи

• Упростить рутинную работу

Page 10: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Задачи

• Упростить рутинную работу

• Уменьшить влияние человеческого фактора

Page 11: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Задачи

• Упростить рутинную работу

• Уменьшить влияние человеческого фактора

• Сделать работу приятнее

Page 12: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Что нам поможет

Будничный Django

Page 13: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Кофе

Page 14: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Пиво

Page 15: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

IDE

Page 16: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Голова и руки

Page 17: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

IDE

Page 18: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Автозаполнение

Page 19: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Переходы по ссылкам

Page 20: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Запуск тестов

Page 21: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Запуск тестов

./manage.py test labbler.audio.TestTranscoding.test_unsupported_format

Page 22: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

PEP8, pylint и прочее

Page 23: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Пишем меньше кода

Page 24: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Пишем меньше повторяющегося кода

Page 25: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Выделение метода/функции

Page 26: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

def users_list(request): ... if user.has_avatar(): avatar = user.avatar else: avatar = DEFAULT_AVATAR

...

def user_profile(request): ... if user.has_avatar(): avatar = user.avatar else: avatar = DEFAULT_AVATAR

...

Page 27: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

def get_avatar(user): if user.has_avatar(): avatar = user.avatar else: avatar = DEFAULT_AVATAR

def users_list(request): ... avatar = get_avatar(user) ...

def user_profile(request): ...

avatar = get_avatar(user)

...

Page 28: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Mixin — расширяем классы

Page 29: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeView(View):

def get_queryset(self): try: page = int(self.request.GET.get("page", 1)) if page < 0: page = 1 except (TypeError, ValueError): page = 1

class SomeAnotherView(View):

def get_queryset(self): try: page = int(self.request.GET.get("page", 1)) if page < 0: page = 1 except (TypeError, ValueError): page = 1

Page 30: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class PaginationMixin(object):

def get_page(self): try: page = int(self.request.GET.get("page", 1)) if page < 0: page = 1 except (TypeError, ValueError): page = 1 return page

class SomeView(View, PaginationMixin):

def get_queryset(self): page = self.get_page()

class SomeAnotherView(View, PaginationMixin):

def get_queryset(self): page = self.get_page()

Page 31: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Важно! Нужно соблюдать меру

Page 32: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

def do_something(obj): return do_something_else(obj)

def do_something_else(obj): return do_something_unexpected(obj)

def do_something_unexpected(obj): return do_something_unbelievable(obj)

def do_something_unbelievable(obj): return do_calculations(obj)

def do_calculations(obj): ...

return result

Page 33: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeMixin(SomeAnotherMixin): ...

class SomeAnotherMixin(OneMoreMixin, AndMoreAgainMinix): ...

class OneMoreMixin(AreYouKiddingMeMixin): ...

class AndMoreAgainMinix(object): ...

class AreYouKiddingMeMixin(object): ...

Page 34: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Декораторы

Page 35: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

from django.db import transaction

def some_view(request):

try:

... transaction.commit()

except: ... transaction.rollback()

Page 36: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

from django.db import transaction

@commit_on_successdef some_view(request):

...

Page 37: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Метапрограммирование

Page 38: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class Base(type): def __new__(cls, name, bases, attrs): new_cls = super(Base, cls).__new__(cls, name, bases, attrs) setattr(new_cls, 'HACKED', "!") return new_cls

class Parent(object): __metaclass__ = Base

class Main(Parent): data = "child"

Метакласс

Page 39: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class Base(type): def __new__(cls, name, bases, attrs): new_cls = super(Base, cls).__new__(cls, name, bases, attrs) setattr(new_cls, 'HACKED', "!") return new_cls

class Parent(object): __metaclass__ = Base

class Main(Parent): data = "child"

Метакласс

Сам метакласс

Page 40: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class Base(type): def __new__(cls, name, bases, attrs): new_cls = super(Base, cls).__new__(cls, name, bases, attrs) setattr(new_cls, 'HACKED', "!") return new_cls

class Parent(object): __metaclass__ = Base

class Main(Parent): data = "child"

Метакласс

Имя класса, который будет сгенерирован

"Parent"

"Main"

Page 41: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class Base(type): def __new__(cls, name, bases, attrs): new_cls = super(Base, cls).__new__(cls, name, bases, attrs) setattr(new_cls, 'HACKED', "!") return new_cls

class Parent(object): __metaclass__ = Base

class Main(Parent): data = "child"

Метакласс

Список классов-родителей

[object]

[Parent]

Page 42: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class Base(type): def __new__(cls, name, bases, attrs): new_cls = super(Base, cls).__new__(cls, name, bases, attrs) setattr(new_cls, 'HACKED', "!") return new_cls

class Parent(object): __metaclass__ = Base

class Main(Parent): data = "child"

Метакласс

Словарь аттрибутов будущего класса

Page 43: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class Base(type): def __new__(cls, name, bases, attrs): new_cls = super(Base, cls).__new__(cls, name, bases, attrs) setattr(new_cls, 'HACKED', "!") return new_cls

class Parent(object): __metaclass__ = Base

class Main(Parent): data = "child"

Метакласс

Parent{ '__metaclass__': < class '__main__.Base' > , '__module__': '__main__'}

Parent{ '__metaclass__': < class '__main__.Base' > , '__module__': '__main__'}

Page 44: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class Base(type): def __new__(cls, name, bases, attrs): new_cls = super(Base, cls).__new__(cls, name, bases, attrs) setattr(new_cls, 'HACKED', "!") return new_cls

class Parent(object): __metaclass__ = Base

class Main(Parent): data = "child"

Метакласс

Main{ 'data': 'child', '__module__': '__main__'}

Main{ 'data': 'child', '__module__': '__main__'}

Page 45: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

>>> print dir(Parent)['HACKED', '__class__', '__delattr__', '__dict__', '__doc__', ...]

>>> print dir(Main)['HACKED', '__class__', '__delattr__', '__dict__', '__doc__', ..., 'data']

Метакласс

Page 46: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Например

Page 47: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

def calls_counter(name, func):

counter_attr_name = "_{0}_calls_counter".format(name)

def counter(instance, *args, **kwargs): setattr(instance, counter_attr_name, getattr(instance, counter_attr_name, 0) + 1) return func(instance, *args, **kwargs)

return counter

Метакласс

Page 48: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class CounterBase(type): def __new__(cls, name, bases, attrs): new_cls = super(CounterBase, cls).__new__(cls, name,

bases, attrs) for obj_name, obj in attrs.items(): if callable(obj) and not isinstance(obj, type): setattr(new_cls, obj_name, calls_counter(obj_name, obj)) return new_cls

Метакласс

Page 49: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeClass(object):

__metaclass__ = CounterBase

def method1(self): pass def method2(self): pass

Метакласс

Page 50: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

>>> p = SomeClass()>>> p.method1()>>> print p._method1_calls_counter1>>> p.method1()>>> print p._method1_calls_counter2>>> p.method2()>>> print p._method2_calls_counter1

Метакласс

Page 51: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Python 2.X

__metaclass__ = Meta

Python 3.X

class X(metaclass=Meta)

Page 52: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Другие будничные проблемы

Page 53: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Повторные вычисления

Page 54: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeClass():

def get_queryset(self): return Entry.objects.all()

def some_action(self): qs = self.get_queryset() return some_calculations(qs)

def another_action(self): qs = self.get_queryset() return another_calculations(qs)

Особенности ORM

Page 55: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

>>> some_obj = SomeClass()>>> some_obj.some_action()>>> len(connection.queries)1>>> some_obj.another_action()>>> len(connection.queries)2

Особенности ORM

Page 56: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeClass():

def __init__(): self.queryset = None

def get_queryset(self): if not self.queryset: self.queryset = Entry.objects.all() return self.queryset

def some_action(self): qs = self.get_queryset() return some_calculations(qs)

def another_action(self): qs = self.get_queryset() return another_calculations(qs)

Обычное решение

Page 57: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

>>> some_obj = SomeClass()>>> some_obj.some_action()>>> len(connection.queries)1>>> some_obj.another_action()>>> len(connection.queries)1

Обычное решение

Page 58: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeClass():

def get_queryset(self): return Entry.objects.all() def get_queryset_1(self): return Entry.objects.filter(something=1) ... def get_queryset_100(self): return Entry.objects.filter(something=100)

А если методов много?

Page 59: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeClass():

def get_queryset(self): return Entry.objects.all() class SomeClass1():

def get_queryset(self): return Entry.objects.all() class SomeClass2():

def get_queryset(self): return Entry.objects.all()

Или классов

Page 60: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeClass():

def __init__(): self.queryset = None self.queryset_1 = None ... self.queryset_100 = None

Так лень

Page 61: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

def methodcache(name=None):

def cache_decorator(func): if not name: cache_name = u"__{0}".format(func.__name__) else: cache_name = name

def field_func(self, *args, **kwargs): if kwargs.pop("force") or not hasattr(self, cache_name): setattr(self, cache_name, func(self, *args, **kwargs)) return getattr(self, cache_name) return field_func return cache_decorator

Декоратор

Page 62: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class SomeClass():

@methodcache(name="queryset") def get_queryset(self): return Entry.objects.all()

@methodcache() def get_queryset_1(self): return Entry.objects.filter(something=1)

class SomeClass1():

@methodcache(name="queryset") def get_queryset(self): return Entry.objects.all()

Декоратор

Page 63: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

>>> some_obj = SomeClass()>>> some_obj.some_action()>>> len(connection.queries)1>>> some_obj.another_action()>>> len(connection.queries)1>>> some_obj.another_action(force=True)>>> len(connection.queries)2

Обычное решение

Page 64: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Можно и Метакласс сделать

Page 65: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

contrib.admin

Page 66: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

def autoregister(): for model in get_models(): try: admin.site.register(model) except AlreadyRegistered: Pass

# urls.pyadmin.autodiscover()autoregister()

Автоматическая регистрация

Page 67: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Без авторегистрации

Page 68: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

С авторегистрацией

Page 69: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class EntryAdmin(admin.ModelAdmin): list_display = ('red_title', 'blue_title')

def red_title(self, obj): return u"""

<font color='red'>{0}</font> """.format(obj.title) red_title.short_description = 'Title' red_title.allow_tags = True

def blue_title(self, obj): return u"""

<font color='blue'>{0}</font> """.format(obj.title) blue_title.allow_tags = True

Методы-поля

Page 70: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Результат

Page 71: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

def func_name(func): name = func.__name__.capitalize() return name.replace("_". " ")

def field(name=None, safe=False):

def field_decorator(func):

def field_func(self, *args, **kwargs): return func(self, *args, **kwargs)

field_func.short_description = name or \ func_name(func) field_func.allow_tags = safe

return field_func return field_decorator

И снова декоратор

Page 72: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

class EntryAdmin(admin.ModelAdmin):

list_display = ('red_title', 'blue_title')

@field("Title", True) def red_title(self, obj): return u""" <font color='red'>{0}</font> """.format(obj.title)

@field(safe=True) def blue_title(self, obj): return u""" <font color='blue'>{0}</font> """.format(obj.title)

Методы-поля

Page 73: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Результат

Page 74: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Если не видно разницы,зачем писать больше? =)

Page 75: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Будничные риски

Page 76: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

XSS. Пассивные и хранимые

Page 77: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Все данные полученные от пользователя, потенциально

опасны

Page 78: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Django вроде сама экранирует?

Page 79: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django<input type="text" name="q"

value="{{ request.GET.q }}">

Page 80: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Почти...

Page 81: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

{% cycle request.GET.q "" %}и

{% firstof request.GET.q1 "" %}

Page 82: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

cycle и firstof

Page 83: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

{% filter force_escape %} {% cycle request.GET.q "" %}

{% firstof request.GET.q1 "" %}

{% endfilter %}

Выход. Django <= 1.5

Page 84: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

{% load cycle from future %}{% load firstof from future %}

{% cycle request.GET.q "" %}

{% firstof request.GET.q1 "" %}

Выход. Django < 1.8

Page 85: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

{% cycle request.GET.q "" %}

{% firstof request.GET.q1 "" %}

Django >= 1.8

Page 86: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Старайтесь не делатьWYSIWYG и |safe

Page 87: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Составьте список разрешенных тегов и обрезайте лишние

Page 88: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

На сервере

Page 89: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

html5lib, BeautifulSoup

Page 90: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Entry.objects.raw()

Page 91: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Entry.objects.raw(""" SELECT * FROM myapp_entry WHERE title = %s""", [title])

Только так

Page 92: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Entry.objects.raw(""" SELECT * FROM myapp_entry WHERE title = %s"""%title)

Но не так

Page 93: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Ну, и чуть-чуть не Python

Page 94: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

user@host:~$ gut push

No command 'gut' found, did you mean: Command 'cut' from package 'coreutils' (main) Command 'git' from package 'git-core' (main)gut: command not found

Не знаю как у вас...

Page 95: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

gut, got, gh

Page 96: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Нам поможет ~/.bashrc

Page 97: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

...

alias gut=gitalias got=gitalias gh=hg

...

~/.bashrc

Page 98: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

user@host:~$ gut pushEverything up-to-date

user@host:~$ got pushEverything up-to-date

~/.bashrc + alias

Page 99: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Еще чуть-чуть лени

ssh -i /path/to/project/key.pem [email protected]

Page 100: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

Делаем скриптик project_ssh

Page 101: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

#!/bin/bash

ssh -i /path/to/project/key.pem [email protected]

~/bin/project_ssh

Page 102: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =

Будничный Django

ssh -i /path/to/project/key.pem [email protected]

./project_ssh

Page 103: Владимир Филонов - kharkivpykharkivpy.org.ua/wp-content/uploads/2013/07/Budnichnyiy...Будничный Django def get_avatar(user): if user.has_avatar(): avatar =