Dec 30, 2011

Extending the Django User model with inheritance

from django.contrib.auth.models import User, UserManager

class CustomUser(User):
    """User with app settings."""
    timezone = models.CharField(max_length=50, default='Europe/London')

    # Use UserManager to get the create_user method, etc.
    objects = UserManager()

...

user = CustomUser.objects.create(...)

# auth_backends.py
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.core.exceptions import ImproperlyConfigured
from django.db.models import get_model

class CustomUserModelBackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        try:
            user = self.user_class.objects.get(username=username)
            if user.check_password(password):
                return user
        except self.user_class.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return self.user_class.objects.get(pk=user_id)
        except self.user_class.DoesNotExist:
            return None

    @property
    def user_class(self):
        if not hasattr(self, '_user_class'):
            self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
            if not self._user_class:
                raise ImproperlyConfigured('Could not get custom user model')
        return self._user_class


# settings.py
AUTHENTICATION_BACKENDS = (
    'myproject.auth_backends.CustomUserModelBackend',
)
...

CUSTOM_USER_MODEL = 'accounts.CustomUser'

http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/

Dec 29, 2011

Monkey patch удаляющий "view on site" кнопку

from django.contrib.auth.models import User
del User.get_absolute_url

Dec 23, 2011

Requests: HTTP for Humans

Очень юзабельное приложение http://docs.python-requests.org/en/latest/index.html

И не менее красивый код https://github.com/kennethreitz/requests/blob/develop/requests/ Есть чему поучиться

Dec 18, 2011

Negative round

>>> str(round(1234.5678, -2))
'1200.0'

Operator overloading for the set builtin

>>> a = set([1,2,3,4])
>>> b = set([3,4,5,6])
>>> a | b # Union
{1, 2, 3, 4, 5, 6}
>>> a & b # Intersection
{3, 4}
>>> a < b # Subset
False
>>> a - b # Difference
{1, 2}
>>> a ^ b # Symmetric Difference
{1, 2, 5, 6}

The Computer Language speed comparison

http://benchmarksgame.alioth.debian.org/


See also: Popularity of Programming Languages

Avoid hardcoding urls

from django.conf import settings

urlpatterns=('',
    ...
    url('^%s$' %settings.LOGIN_URL[1:], 'django.contrib.auth.views.login', 
        name="login")
    ...
)

Django model to dict

from django.forms.models import model_to_dict
model_to_dict(intance, fields=[], exclude=[])

Include tag

<h1>Most sold items</h1>
{% include "items.html" with items=most_sold_items only %}

<h1>Latest items</h1>
{% include "items.html" with items=latest_items only %}

Dec 16, 2011

Readonly Tabluar Inline

# admin.py

class ReadonlyTabularInline(admin.TabularInline):
    can_delete = False
    extra = 0
    editable_fields = []
    
    def get_readonly_fields(self, request, obj=None):
        fields = []
        for field in self.model._meta.get_all_field_names():
            if (not field == 'id'):
                if (field not in self.editable_fields):
                    fields.append(field)
        return fields
    
    def has_add_permission(self, request):
        return False
    

# Usage Example (admin.py)

class FixturesInline(ReadonlyTabularInline):
    model = models.Fixture
    verbose_name_plural = _('List of unpublished Fixtures')
    editable_fields = ['public']



# My models.py (a part of)

class Competition(models.Model):
    name = models.CharField(max_length=200)
    location = models.ForeignKey(Location)

class Fixture(models.Model):
    competition = models.ForeignKey(Competition)
    conference = models.BooleanField()
    home_team = models.ForeignKey(Team, related_name='hometeam')
    guest_team = models.ForeignKey(Team, related_name='guestteam')
    datetime = models.DateTimeField()
    public = models.BooleanField()
    channels = models.ManyToManyField(ChanSatMembership)
    additional_infos = models.TextField(blank=True, null=True)

Form preview

Django comes with an optional “form preview” application

CommonMiddleware

...
Performs URL rewriting based on the APPEND_SLASH and PREPEND_WWW settings.
...

Dec 13, 2011

File

Best way to temporarily unzip a file

gzip.open(zipfile).read()  # will give you the contents of the file in a single string.
with open(tmpfile, "wb") as tmp:
    shutil.copyfileobj(gzip.open(zipfile), tmp)

Date, Time

Pythonic way to add date.timedate and datetime.time objects


>>> datetime.datetime.combine(datetime.date(2011, 01, 01), datetime.time(10, 23))
datetime.datetime(2011, 1, 1, 10, 23)

Dec 9, 2011

Экстремальное программирование. Разработка через тестирование

Качество разработанных тестов оценивается методами:
  • Покрытие операторов кода (statement coverage)
  • Намеренное добавление дефекта (defect insertion)
Паттерны разработки основанной на тестах
  • Тест. Отговорка что на тесты нет времени не совсем коректна, так как приложение все равно тестируется, но руками. Но автоматические тесты намного быстрее! Кроме того тесты снижают уровень стресса
  • Изолированный тест (Isolated Test) - основная причина производительность
  • Список тестов (Test List)
  • Вначале тест (Test First)
  • Вначале оператор assert (Assert First)
  • Тестовые данные (Test Data)
  • Понятные данные (Evident Data). Иногда, если данные используются только в одном методе, для лучшей читабельности можно использовать магические числа
Паттерны красной полосы
  • One Test Step
  • Starter Test (Начальный тест)
  • Explanation Test (Объясняющий тест). Тесты могут служить для объяснения кода
  • Learning Test (Тест для обучения)
  • Another Test
  • Regression Test
  • Break
  • Do Over (Начать сначала). Иногда лучше начать заново, чем пытаться довести до ума кривой код
  • Cheap Desk, Nice Chear. Ну, в общем, хорошее кресло решает..
Паттерны тестирования
  • Дочерний тест (Child Test)
  • Mock Object
  • Self Shunt (Самошунтирование). Как можно убедиться что один объект корректно взаимодействует с другим? Можно заставить тестируемый объект взаимодействовать не с целевым объектом, а с тестом.
        def testNotification(self):
            self.count = 0
            result = TestResult()
            result.addListener(self)
            WasRun('testMethod').run(result)
            self.assertEqual(1, self.count)
    
        def startTest(self):
            self.count = self.count + 1
  • Log String (Строка журнал). Полезен когда важен порядок операций. Хорошо сочетается с Self Shunt. Объект-тест реализует методы шунтируемого интерфейса таким образом, что каждый из них добавляет строку в журнал, затем проверяется корректность этих записей.
  • Crush Test Dummy (Тестирование обработки ошибок). Применяется когда надо протестировать как отрабатывает код по обработке ошибки, возникновение которой маловероятно. Для этого создается фэйковый объект который вместо реальной работы генерирует исключение.
  • Broken Test
  • Clean Check-In
Паттерны зеленой полосы
  • Fake It (Подделка)
  • Triangulate
  • Obvious Implemetnation (Очевидная реализация)
  • One To Many (От одного ко многим). Как реализовать работу с коллекцией объектов? Сначала реализуется для одного объекта, затем модернизируется для работы с коллекцией. 
Паттерны xUnit
  • Assertion
  • Fixture
  • External Fixture. Ресурсы освобождаются в tearDown()
  • Test Method
  • Exception Test
  • All Tests

Dec 4, 2011

get_list_or_404


get_list_or_404(klass*args**kwargs)
Returns the result of filter() on a given model manager, raising Http404 if the resulting list is empty.