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



melbdjango-demo

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

API link

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

queryset.py

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

pipelines.py

Use CASES


python-social-auth

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):
         ...  

django-sherlock

USE cases


django-rest-framework
django-tastypie
django-nap

many more...
inspired by...

Django

learnt something new today?




we're hiring

Made with Slides.com