SlideShare ist ein Scribd-Unternehmen logo
1 von 22
Downloaden Sie, um offline zu lesen
2013




            - Good Practices

selective ly and subjectively..
Who?


      Justyna Żarna
Woman in Django / Python World



     @Ustinez


     http://solution4future.com
About?
1. Models:
   a) a signal to warm-up,
   b) migrations,
   c) let's focus on User.

2. Views:
    a) class-based views.

3. Templates:
    a) customization.

3. Tools:
    a) no one likes queue..,
    b) extend and explore.
Model layer - the warm up

1. Save vs Signals:

def save(self, *args, **kwargs):
    #we already have predefined sponsor's types, so we can't add next the same type
    if self.type in ("Silver", "Gold", "Platinum"):
        return                                      good usage
    else:
        super(Sponsor, self).save(*args, **kwargs)

def save(self, *args, **kwargs):
   self.increment_sponsors_number()                                              bad usage
    super(Event, self).save(*args, **kwargs)

a common mistake: forgetting *args, **kwargs
When an object is saving..

1. Emit a pre-signal.

2. Pre-process the data (automated modification for "special
behavior fields").
   for example:
   DateField with attribute: auto_now = True

3. Preparation the data for the database.
   for example:
   DateField and datetime object is prepared to date string in ISO,
   but simple data types are ready

4. Insert to database.

5. Emit a post-signal.
Django is sending us the signal..

1. Realization of Observer design pattern.
2. Applications, pieces of code get notifications about defined
actions.
3. List of available signals:
    a) pre_init, post_init,
    b) pre_save, post_save,                      write your own signal
    c) pre_delete, post_delete,
    d) m2m_changed,
    e) request_started, request_finished.
4. Listening to signals.
   def hello_function(Sponsor,              @receiver(post_save, sender=Event)
   **kwargs):                               def hello_function(sender, **kwargs)
        print ('Hello. I'm new Sponsor!')        print ('Hello! I'm new Event!')
   post_save.connect(hello_function)
Race condition problem

1. Separate process, threads depend on shared resource.

2. When operations are atomic, shared resource is safe.

3. Problem is difficult to debug, non deterministic and depends
on the relative interval of access to resource.

4. Good designed project avoids this problem.


Example:
   Gamification, Scoring System, Optimalization, Statistics,
Raports etc etc..
Compile all information

class Movie(models.Model)
     title = models.CharField(max_length = 250, verbose_name='title')
     lib = models.ForeignKey(Library, verbose_name='library')

class Library
    movie_counter = models.IntegerField(default = 0, 'how many movies?')

@receiver(post_save, sender=Movie)
   def add_movie_handler(sender, instance, created, **kwargs):
   if created:
       instance.lib.movie_counter += 1
       instance.lib.save()

@receiver(post_save, sender=Movie)
def add_movie_handler(sender, instance, created, **kwargs):
   if created:
       instance.lib.movie_counter = F(movie_counter) + 1
       instance.lib.save()
Migrations - South

1. Schemamigration:
   Schema evolution, upgrade database schema, history of changes and
   possibility to move forward and backward in this history.

   ./manage.py schemamigration myapp --auto

2. Datamigration:
   Data evolution.

   ./manage.py datamigration myapp update_title

   def forwards(self, orm):
        for lib in Library.objects.all():
              lib.movie_counter = 100
              lib.save()
Migration - south

3. Updating migrations:
   ./manage.py schemamigration myapp --auto --update
   or...
   ./manage.py shell
   form south.models import MigrationHistory
   migration = MigrationHistory.objects.get(migration = "example_name")
   migration.delete()


4. Team work - merging migrations:
   ./manage.py migrate --list
   ./manage.py schemamigration --empty myapp merge_models


5. Migration:
   ./manage.py migrate

5. Fixtures - yaml serialization.
Focus on old User

Before 1.5

class Profile(models.Model):
     user = models.OneToOneField(User, related_name='profile')
     city = models.CharField(max_length=255, verbose_name=u'city')
     street = models.CharField(max_length=255, verbose_name=u'street')
     house_number = models.CharField(max_length=255, verbose_name=u'home
nr')
     zip_code = models.CharField(max_length=6, verbose_name=u'zip code')
class MyUser(User):
    def city_and_code(self):
         return '%s %s' % (self.city, self.zip_code)
    class Meta:
        verbose_name = u"User"
        verbose_name_plural = u"Users"
        db_table = "account_profile"
        proxy = True
Focus on new User

Django 1.5
1. The simplest way to customize User:
class MyUser(AbstractBaseUser):
    uuid = models.CharFieldField(max_length = 10, unique = True, verbose_name
= "user uuid")
   USERNAME_FIELD = (uuid) # unique identifier
   REQUIRED_FIELDS = ('first_name') # mandatory fields for createsuperuser
management command

AbstractBaseUser provides only core implementation of User
with hashed passwords and password reset and only few basic
method like: is_authenticated(), get_full_name(), is_active() etc.
AbstractBaseUser is dedicated simple changes for User, not
creating full profile.
Focus on new User

2. Extend User like profile:
class MyUser(AbstractUser):
    city = models.CharField(max_length=255, verbose_name=u'city')
    street = models.CharField(max_length=255, verbose_name=u'street')
    house_number = models.CharField(max_length=255, verbose_name=u'home
    number')
    zip_code = models.CharField(max_length=6, verbose_name=u'zip code')




AbstractUser provides full implementation of the Django's
default User and UserAdmin is available.
Class-based views

Functional approach:

def get_big_libs(request):
     context = {}
     context['libs'] = lLibrary.objects.filter(movie_counter__gt = 120)
  return render_to_response('template_name.html', {'context': context},
context_instance=RequestContext(request))



Problems:
1. A repetitive constructions...
2. Low reusability of the code...
3. Negation of the principle of DRY...
4. Bad readability, monotonicity...
Class-based views
New approach:
from django.conf.urls import patterns, url, include
from django.views.generic import ListView
from myapp.models import Library
urlpatterns = patterns('',
   (r'^library/$', ListView.as_view(
      queryset=Library.objects.filter(movie_counter__gt = 120),
      context_object_name="libs_list")),
)

Extending example:
urlpatterns = patterns('',
   (r'^library/(?P<counter>d+)/$', LibraryListView.as_view()),
)
class LibraryListView(ListView):
   context_object_name = "libs_list"
   template_name = "libs.html"
   def get_queryset(self):
       return Library.object.filter(movie_counter__gt=self.args[0])
Advantages
1. Class with all benefits:
    a) inheritance.

2. Generalization.

3. DRY.

4. Fast and simple for common usage.

5. Fast prototyping.

6. Easy and clean extending and customization.
Templates - custom tags and filters
Approach lazy developer:
def view1(request):
     context = {}
     context['config'] = {'a': [1,2,3], 'b': ['a', 'b', 'c', 'd', 'e', 'f'']}
     context['key'] = request.GET.get('key')
     context['key_options_from_config'] = context['config'][context['key']]
     return render_to_response('template_name.html', {'context': context})

In template: {% if key_options_from_config %} TODO {% endif %}

Other really lazy developer write this:
@register.filter(name='get_val')                                      reusable snippet
def val(value, key):                                                  reusable filter
     return value[key] if value.get(key) else False

TEMPLATE:
{% if config|get_val:key %}
     TODO
{% endif %}
No one likes queue?

Celery is an asynchronous tasks queue.

Celery in meantime of request send some async tasks to
queue and do some computation.

Celery is working with Kombu and RabbitMQ and various
backends for example Redis etc..

Destination: messaging systems, cron task, calculations etc..
Celery tasks
Examples:

1. Cron jobs in Python code (no need to configurate or order
cron jobs on server or writing command).

2. Throttled tasks.

3. Delayed tasks.

4. Move heavy load jobs to workers on other machines.
(application will not suffer on preformance).

5. Chaining tasks.
In action


@task
def delete_fake_libraries():
   for lib in Library.objects.all():
       if lib.movie_counter == 0 and lib.book_counter == 0:
             lib.delete()


CELERYBEAT_SCHEDULE = {
  'check_campaign_active': {'task': myapp.tasks.
delete_fake_libraries', 'schedule': crontab(minute='59',
hour='23'), 'args': None},
}
Explore..




photo by Grzegorz Strzelczyk
Thank you :))

Weitere ähnliche Inhalte

Was ist angesagt?

DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
Graham Dumpleton
 
Unbreaking Your Django Application
Unbreaking Your Django ApplicationUnbreaking Your Django Application
Unbreaking Your Django Application
OSCON Byrum
 
Apache ant
Apache antApache ant
Apache ant
koniik
 
The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of Django
Jacob Kaplan-Moss
 
Nanocloud cloud scale jvm
Nanocloud   cloud scale jvmNanocloud   cloud scale jvm
Nanocloud cloud scale jvm
aragozin
 
Apache Ant
Apache AntApache Ant
Apache Ant
Ali Bahu
 

Was ist angesagt? (20)

Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
Practical Celery
Practical CeleryPractical Celery
Practical Celery
 
Puppet modules: An Holistic Approach
Puppet modules: An Holistic ApproachPuppet modules: An Holistic Approach
Puppet modules: An Holistic Approach
 
AppSec USA 2015: Customizing Burp Suite
AppSec USA 2015: Customizing Burp SuiteAppSec USA 2015: Customizing Burp Suite
AppSec USA 2015: Customizing Burp Suite
 
JavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and KarmaJavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and Karma
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
 
Unbreaking Your Django Application
Unbreaking Your Django ApplicationUnbreaking Your Django Application
Unbreaking Your Django Application
 
Javascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and GulpJavascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and Gulp
 
Apache ant
Apache antApache ant
Apache ant
 
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
Hear no evil, see no evil, patch no evil: Or, how to monkey-patch safely.
 
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
 
The Best (and Worst) of Django
The Best (and Worst) of DjangoThe Best (and Worst) of Django
The Best (and Worst) of Django
 
Nagios Conference 2011 - Michael Medin - Workshop: Scripting On The Windows Side
Nagios Conference 2011 - Michael Medin - Workshop: Scripting On The Windows SideNagios Conference 2011 - Michael Medin - Workshop: Scripting On The Windows Side
Nagios Conference 2011 - Michael Medin - Workshop: Scripting On The Windows Side
 
Introduction to Apache Ant
Introduction to Apache AntIntroduction to Apache Ant
Introduction to Apache Ant
 
Ajax Performance
Ajax PerformanceAjax Performance
Ajax Performance
 
Nanocloud cloud scale jvm
Nanocloud   cloud scale jvmNanocloud   cloud scale jvm
Nanocloud cloud scale jvm
 
Beyond Unit Testing
Beyond Unit TestingBeyond Unit Testing
Beyond Unit Testing
 
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developersSoftshake 2013: 10 reasons why java developers are jealous of Scala developers
Softshake 2013: 10 reasons why java developers are jealous of Scala developers
 
Apache Ant
Apache AntApache Ant
Apache Ant
 

Ähnlich wie Django Good Practices

WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
Active Support Core Extension (2)
Active Support Core Extension (2)Active Support Core Extension (2)
Active Support Core Extension (2)
RORLAB
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
Graham Dumpleton
 

Ähnlich wie Django Good Practices (20)

Django Pro ORM
Django Pro ORMDjango Pro ORM
Django Pro ORM
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
What's new in Django 1.2?
What's new in Django 1.2?What's new in Django 1.2?
What's new in Django 1.2?
 
Data herding
Data herdingData herding
Data herding
 
Data herding
Data herdingData herding
Data herding
 
Python Metaprogramming
Python MetaprogrammingPython Metaprogramming
Python Metaprogramming
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Art & music vs Google App Engine
Art & music vs Google App EngineArt & music vs Google App Engine
Art & music vs Google App Engine
 
Active Support Core Extension (2)
Active Support Core Extension (2)Active Support Core Extension (2)
Active Support Core Extension (2)
 
Patterns in Python
Patterns in PythonPatterns in Python
Patterns in Python
 
Introduction to c_plus_plus (6)
Introduction to c_plus_plus (6)Introduction to c_plus_plus (6)
Introduction to c_plus_plus (6)
 
Introduction to c_plus_plus
Introduction to c_plus_plusIntroduction to c_plus_plus
Introduction to c_plus_plus
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
 
Django at Scale
Django at ScaleDjango at Scale
Django at Scale
 
Object.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examplesObject.__class__.__dict__ - python object model and friends - with examples
Object.__class__.__dict__ - python object model and friends - with examples
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrid
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrid
 
Viktor Tsykunov: Azure Machine Learning Service
Viktor Tsykunov: Azure Machine Learning ServiceViktor Tsykunov: Azure Machine Learning Service
Viktor Tsykunov: Azure Machine Learning Service
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2
 
Node.js Patterns for Discerning Developers
Node.js Patterns for Discerning DevelopersNode.js Patterns for Discerning Developers
Node.js Patterns for Discerning Developers
 

Kürzlich hochgeladen

Kürzlich hochgeladen (20)

Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at Comcast
 
How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024Top 10 Symfony Development Companies 2024
Top 10 Symfony Development Companies 2024
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
 
What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024
 
The UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, OcadoThe UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, Ocado
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
PLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsPLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. Startups
 
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová10 Differences between Sales Cloud and CPQ, Blanka Doktorová
10 Differences between Sales Cloud and CPQ, Blanka Doktorová
 

Django Good Practices

  • 1. 2013 - Good Practices selective ly and subjectively..
  • 2. Who? Justyna Żarna Woman in Django / Python World @Ustinez http://solution4future.com
  • 3. About? 1. Models: a) a signal to warm-up, b) migrations, c) let's focus on User. 2. Views: a) class-based views. 3. Templates: a) customization. 3. Tools: a) no one likes queue.., b) extend and explore.
  • 4. Model layer - the warm up 1. Save vs Signals: def save(self, *args, **kwargs): #we already have predefined sponsor's types, so we can't add next the same type if self.type in ("Silver", "Gold", "Platinum"): return good usage else: super(Sponsor, self).save(*args, **kwargs) def save(self, *args, **kwargs): self.increment_sponsors_number() bad usage super(Event, self).save(*args, **kwargs) a common mistake: forgetting *args, **kwargs
  • 5. When an object is saving.. 1. Emit a pre-signal. 2. Pre-process the data (automated modification for "special behavior fields"). for example: DateField with attribute: auto_now = True 3. Preparation the data for the database. for example: DateField and datetime object is prepared to date string in ISO, but simple data types are ready 4. Insert to database. 5. Emit a post-signal.
  • 6. Django is sending us the signal.. 1. Realization of Observer design pattern. 2. Applications, pieces of code get notifications about defined actions. 3. List of available signals: a) pre_init, post_init, b) pre_save, post_save, write your own signal c) pre_delete, post_delete, d) m2m_changed, e) request_started, request_finished. 4. Listening to signals. def hello_function(Sponsor, @receiver(post_save, sender=Event) **kwargs): def hello_function(sender, **kwargs) print ('Hello. I'm new Sponsor!') print ('Hello! I'm new Event!') post_save.connect(hello_function)
  • 7. Race condition problem 1. Separate process, threads depend on shared resource. 2. When operations are atomic, shared resource is safe. 3. Problem is difficult to debug, non deterministic and depends on the relative interval of access to resource. 4. Good designed project avoids this problem. Example: Gamification, Scoring System, Optimalization, Statistics, Raports etc etc..
  • 8. Compile all information class Movie(models.Model) title = models.CharField(max_length = 250, verbose_name='title') lib = models.ForeignKey(Library, verbose_name='library') class Library movie_counter = models.IntegerField(default = 0, 'how many movies?') @receiver(post_save, sender=Movie) def add_movie_handler(sender, instance, created, **kwargs): if created: instance.lib.movie_counter += 1 instance.lib.save() @receiver(post_save, sender=Movie) def add_movie_handler(sender, instance, created, **kwargs): if created: instance.lib.movie_counter = F(movie_counter) + 1 instance.lib.save()
  • 9. Migrations - South 1. Schemamigration: Schema evolution, upgrade database schema, history of changes and possibility to move forward and backward in this history. ./manage.py schemamigration myapp --auto 2. Datamigration: Data evolution. ./manage.py datamigration myapp update_title def forwards(self, orm): for lib in Library.objects.all(): lib.movie_counter = 100 lib.save()
  • 10. Migration - south 3. Updating migrations: ./manage.py schemamigration myapp --auto --update or... ./manage.py shell form south.models import MigrationHistory migration = MigrationHistory.objects.get(migration = "example_name") migration.delete() 4. Team work - merging migrations: ./manage.py migrate --list ./manage.py schemamigration --empty myapp merge_models 5. Migration: ./manage.py migrate 5. Fixtures - yaml serialization.
  • 11. Focus on old User Before 1.5 class Profile(models.Model): user = models.OneToOneField(User, related_name='profile') city = models.CharField(max_length=255, verbose_name=u'city') street = models.CharField(max_length=255, verbose_name=u'street') house_number = models.CharField(max_length=255, verbose_name=u'home nr') zip_code = models.CharField(max_length=6, verbose_name=u'zip code') class MyUser(User): def city_and_code(self): return '%s %s' % (self.city, self.zip_code) class Meta: verbose_name = u"User" verbose_name_plural = u"Users" db_table = "account_profile" proxy = True
  • 12. Focus on new User Django 1.5 1. The simplest way to customize User: class MyUser(AbstractBaseUser): uuid = models.CharFieldField(max_length = 10, unique = True, verbose_name = "user uuid") USERNAME_FIELD = (uuid) # unique identifier REQUIRED_FIELDS = ('first_name') # mandatory fields for createsuperuser management command AbstractBaseUser provides only core implementation of User with hashed passwords and password reset and only few basic method like: is_authenticated(), get_full_name(), is_active() etc. AbstractBaseUser is dedicated simple changes for User, not creating full profile.
  • 13. Focus on new User 2. Extend User like profile: class MyUser(AbstractUser): city = models.CharField(max_length=255, verbose_name=u'city') street = models.CharField(max_length=255, verbose_name=u'street') house_number = models.CharField(max_length=255, verbose_name=u'home number') zip_code = models.CharField(max_length=6, verbose_name=u'zip code') AbstractUser provides full implementation of the Django's default User and UserAdmin is available.
  • 14. Class-based views Functional approach: def get_big_libs(request): context = {} context['libs'] = lLibrary.objects.filter(movie_counter__gt = 120) return render_to_response('template_name.html', {'context': context}, context_instance=RequestContext(request)) Problems: 1. A repetitive constructions... 2. Low reusability of the code... 3. Negation of the principle of DRY... 4. Bad readability, monotonicity...
  • 15. Class-based views New approach: from django.conf.urls import patterns, url, include from django.views.generic import ListView from myapp.models import Library urlpatterns = patterns('', (r'^library/$', ListView.as_view( queryset=Library.objects.filter(movie_counter__gt = 120), context_object_name="libs_list")), ) Extending example: urlpatterns = patterns('', (r'^library/(?P<counter>d+)/$', LibraryListView.as_view()), ) class LibraryListView(ListView): context_object_name = "libs_list" template_name = "libs.html" def get_queryset(self): return Library.object.filter(movie_counter__gt=self.args[0])
  • 16. Advantages 1. Class with all benefits: a) inheritance. 2. Generalization. 3. DRY. 4. Fast and simple for common usage. 5. Fast prototyping. 6. Easy and clean extending and customization.
  • 17. Templates - custom tags and filters Approach lazy developer: def view1(request): context = {} context['config'] = {'a': [1,2,3], 'b': ['a', 'b', 'c', 'd', 'e', 'f'']} context['key'] = request.GET.get('key') context['key_options_from_config'] = context['config'][context['key']] return render_to_response('template_name.html', {'context': context}) In template: {% if key_options_from_config %} TODO {% endif %} Other really lazy developer write this: @register.filter(name='get_val') reusable snippet def val(value, key): reusable filter return value[key] if value.get(key) else False TEMPLATE: {% if config|get_val:key %} TODO {% endif %}
  • 18. No one likes queue? Celery is an asynchronous tasks queue. Celery in meantime of request send some async tasks to queue and do some computation. Celery is working with Kombu and RabbitMQ and various backends for example Redis etc.. Destination: messaging systems, cron task, calculations etc..
  • 19. Celery tasks Examples: 1. Cron jobs in Python code (no need to configurate or order cron jobs on server or writing command). 2. Throttled tasks. 3. Delayed tasks. 4. Move heavy load jobs to workers on other machines. (application will not suffer on preformance). 5. Chaining tasks.
  • 20. In action @task def delete_fake_libraries(): for lib in Library.objects.all(): if lib.movie_counter == 0 and lib.book_counter == 0: lib.delete() CELERYBEAT_SCHEDULE = { 'check_campaign_active': {'task': myapp.tasks. delete_fake_libraries', 'schedule': crontab(minute='59', hour='23'), 'args': None}, }