Learning Design Patterns from django


@namngology
github.com/geeknam

ABOUT


Developer

   

Kogan donates $10k to DSF 

WE ARE HIRING !!!


DJANGo philosophies

DJANGO design pattern examples

SIMPLE EXAMPLES

USE CASES



WHY DO WE CARE?

Django PHILOSOPHIES


Loose COUPLING
LESS CODE
QUICK DEVELOPMENT
DRY
CONSISTENCY


DJANGO ORM


 Developer.objects.filter(
    city='Melbourne', language='python', framework='Django'
 )

LESS CODE

QUICK DEVELOPMENT

Example


Quick & dirty

 import requests
 
 url = '.../api/product/?department=televisions&order_by=price'
 
 data = requests.get(url).json()
 objects = data['objects']

 for object in objects:
     ...

WHY NOT?


 Product.objects.filter(department='televisions'
 ).filter(category='led-tv').order_by('price')

Chain methods

MAKE THEM LAZY

CACHE RESULTS

Return Objects


USE cases


Querying REST API
Querying external services
Client libraries


django-haystack

MIDDLEWARE & CONTEXT PROCESSORS

 MIDDLEWARE_CLASSES = (
    'django.middleware.gzip.GZipMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
 )

 TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.auth.context_processors.auth",
    "django.core.context_processors.request",
 )

Loose coupling
Plugable

Example


Email Validator


 email = 'sOmeEmail@MelbDjango.com'
 
 def validate_email(email):
     if '@' not in email:
         raise ValidationError('Invalid email. @ not found')
     if '.' not in email:
         raise ValidationError('Invalid email. Incorrect domain?')

     # lowercase domain
     name, domain = email.split('@')
     email = '@'.join([name, domain.lower()])

WE can do it this way

 PIPELINE = (
    'validation.contains_dot',
    'validation.contains_at',
    'mutators.lowercase_domain',
    'mutators.lowercase_name',
 )


 email = EmailValidator('sOmeEmail@MelbDjango.com').email

 print email
 > 'someemail@melbdjango.com'

PIPELINES

IMPORT MODULES

Use CASES


MIXINS (CBV)


 class ListView(MultipleObjectTemplateResponseMixin, BaseListView):    pass

LESS CODE

REUSABLE

Example

 class Price(object):
    def __init__(self, amount):
        self.amount = amount

 class Discount(object):
    def __init__(self, amount, expiry_date=None):
        self.amount = amount
        if expiry_date:
            self.expiry_date = expiry_date
        else:
            self.expiry_date = datetime.now()

    @property
    def expired(self):
        return self.expiry_date < datetime.now()


They are comparable


 class ComparableMixin(object):

    def __lt__(self, other):
        return self.amount < other.amount

    def __eq__(self, other):
        return self.amount == other.amount

    def __gt__(self, other):
        return self.amount > other.amount

    def __ne__(self, other):
        return self.amount != other.amount


BEWARE !!!


Method resolution order

LEFT > RIGHT


Meta OPTIOns


 class Developer(models.Model):
     ...

     class Meta:
         verbose_name_plural = 'Monkeys'
         permissions = (
             ('can_code', 'Can smash the keyboard')
         )

METACLASS

EXAMPLE


@receiver(post_save, sender=Developer)
def do_something(sender, instance=None, **kwargs):
    ...

@receiver(pre_delete, sender=Developer)
def do_something_else(sender, instance=None, **kwargs):
    ...@receiver(drinks_coffee, sender=Developer)
def max_focus(sender, instance=None, **kwargs):
    ...
@receiver(reads_hacker_news, sender=Developer) def min_focus(sender, instance=None, **kwargs): ...

Add some magic



 class DeveloperObserver(ModelObserver):

     class Meta:
         model = Developer

     def post_save_receiver(self, instance, **kwargs):
         ...

     def drinks_coffee_receiver(self, instance, **kwargs):
         ...

     def reads_hacker_news_receiver(self, instance, **kwargs):
         ...  

USE cases


django-rest-framework
django-tastypie
django-nap

many more...
inspired by...

Django

learnt something new today?




we're hiring

Learning Design Patterns from django

By Nam Ngo

Learning Design Patterns from django

  • 848