SlideShare a Scribd company logo
Powerful Generic Patterns With Django
POWERFUL GENERIC PATTERNSDjango's Content Types Framework
CONTENTTYPESAn application that can track all of the models installed in your Django-powered project, providing a high-level, generic interface for working with your models
SAY WHAT ?
CONTENTTYPES----------------------------------------|   name   |   app_label   |   model   ||   post   |   blogger     |   post    ||   blog   |   blogger     |   Blog    ||   like   |   likeable    |   Like    |----------------------------------------
PROBLEMblog = Blog.objects.get( pk = 1 )posts = Post.objects.filter( blog = blog )features = Post.objects.filter( feature = True )3+ URLs3+ view function3+ templates
PROBLEMblog = Blog.objects.get( pk = 1 )posts = Post.objects.filter( blog = blog )features = Post.objects.filter( feature = True ){%for post in posts %}{{ post.title }} {{ post.like_set.count }} likes{%endfor%}
GENERIC VIEWS?
GENERIC VIEWS?Take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to write too much code
GENERIC VIEWS?from django.views.generic import list_detaildefmy_view( request ):return list_detail.object_list(              queryset=Post.objects.all()    )
NOT SO GENERIC VIEWSfrom django.views.generic import list_detaildefmy_view( request ):return list_detail.object_list(              queryset=Post.objects.all()    )
NOT SO GENERIC VIEWS
NOT SO GENERIC VIEWSTo Use A Generic View You Need...A Queryset
A Model + ID
A Model + Slug
A Model + Slug FieldMORE PROBLEMSclassPost(models.Model):   title = models.CharField()   blog  = models.ForeignKey( Blog )   body  = models.TextField()   slug  = models.SlugField()   likers = models.ForeignKey( User )   likes = models.IntegerField()BlogPostPost LikesPost Likers
MORE PROBLEMSclassFeature(models.Model):   title = models.CharField()   post  = models.ForeignKey( Post )   likers = models.ForeignKey( User )   likes = models.IntegerField()
CONTENTTYPESAn application that can track all of the models installed in your Django-powered project, providing a high-level, generic interface for working with your models
CONTENTTYPESUse the ORM without knowing what kind of objects you might be working with.
CONTENTTYPESUse the ORM without knowing what kind of objects you might be working with. EVER.
CONTENTTYPESYour ModelContentTypeModel AModel CModel B
GENERIC FOREIGNKEYfrom django.contrib.contenttypes.models importContentTypefrom django.contrib.contenttypes importgenericclassFeature(models.Model):   content_type = models.ForeignKey (ContentType)   object_id    = models.PositiveIntegerField()   content_object = generic.GenericForeignKey('content_type'                           ,'object_id'                                              )
MAGIC BITSclassFeature(models.Model):   content_type = models.ForeignKey (ContentType)   object_id    = models.PositiveIntegerField()   content_object = generic.GenericForeignKey(   'content_type'                                           ,'object_id'                                              )
MAGIC BITSclassFeature(models.Model):   content_type = models.ForeignKey (ContentType)   object_id    = models.PositiveIntegerField()   content_object = generic.GenericForeignKey('content_type'                                              ,'object_id'                                              )
MAGIC BITSclassFeature(models.Model):   content_type = models.ForeignKey (ContentType)   object_id    = models.PositiveIntegerField()   content_object = generic.GenericForeignKey('content_type'                                              ,'object_id'                                              )
GENERIC FOREIGNKEY>>>  obj = Feature.objects.get( pk = 1 )>>>  obj.content_object>>>  <Post: Hello World>>>>  obj = Feature.objects.get( pk = 2 )>>>  obj.content_object>>>  <Blog: The Best Blog>>>>  obj = Feature.objects.get( pk = 3 )>>>  obj.content_object>>>  <Anything: Whatever You Want>
GENERIC FOREIGNKEY
GENERIC FOREIGNKEYclassPost(models.Model):   title = models.CharField()   blog  = models.ForeignKey( Blog )   body  = models.TextField()   slug  = models.SlugField()classLike( models.Model ):  content_type   = models.ForeignKey( ContentType )  object_id      = models.PositiveIntegerField()  content_object = generic.GenericForeignKey( ... )  likers         = models.ManyToMany( User )
GOTCHA!Models are NOT aware of their Content Type
MORE PROBLEMSclassLike( models.Model ):  content_type   = models.ForeignKey( ContentType )  object_id      = models.PositiveIntegerField()  content_object = generic.GenericForeignKey( ... )  likers         = models.ManyToMany( User )
MORE PROBLEMSclassLike( models.Model ):  content_type   = models.ForeignKey( ContentType )  object_id      = models.PositiveIntegerField()  content_object = generic.GenericForeignKey( ... )  likers         = models.ManyToMany( User )deflike_view( request, object_id ):    post = Post.objects.get( pk = object_id )    like = Like( object_id = post, ??? )
GENERIC GEMSfrom django.contrib.contenttypes.models importContentTypefrom django.contrib.auth.models importUser>>> type = ContentType.objects.get_for_model( User )>>> type>>> <ContentType: user >>>> model = type.model_class()>>> model>>> <class: 'django.contrib.auth.models.User'>
GENERIC GEMS
PATTERN #1
PATTERN #1Self-Aware Model
SELF AWARE MODELclassSelfAwareModel(models.Model):  def get_ct( self ):''' Returns the Content Type for this instance'''return ContentType.objects.get_for_model(self)def get_ct_id( self ):''' Returns the id of the content type for this instance'''return self.get_ct().pkdef get_app_label( self ):return self.get_ct().app_labeldef get_model_name( self ):return self.get_ct().modelclassMeta:       abstract = True
SELF AWARE MODELclassSelfAwareModel(models.Model):  def get_ct( self ):''' Returns the Content Type for this instance'''return ContentType.objects.get_for_model(self)def get_ct_id( self ):''' Returns the id of the content type for this instance'''return self.get_ct().pkdef get_app_label( self ):return self.get_ct().app_labeldef get_model_name( self ):return self.get_ct().modelclassMeta:       abstract = TrueCACHED BY DJANGO
SELF AWARE MODELclassSelfAwareModel(models.Model):  def get_ct( self ):''' Returns the Content Type for this instance'''return ContentType.objects.get_for_model(self)def get_ct_id( self ):''' Returns the id of the content type for this instance'''return self.get_ct().pkdef get_app_label( self ):return self.get_ct().app_labeldef get_model_name( self ):return self.get_ct().modelclassMeta:       abstract = TrueCACHED BY DJANGOself.__class__._cache[self.db][key]
SELF AWARE EVERYTHINGclassPost( SelfAwareModel ):   title = models.CharField()   blog  = models.ForeignKey( Blog )   body  = models.TextField()   slug  = models.SlugField()   likers = models.ForeignKey( User )   likes = models.IntegerField()
SELF AWARE EVERYTHINGclassPost( SelfAwareModel ):   title = models.CharField()   blog  = models.ForeignKey( Blog )   body  = models.TextField()   slug  = models.SlugField()   likers = models.ForeignKey( User )   likes = models.IntegerField()ALL MODELSSUBCLASSESELFAWAREMODEL
SELF AWARE EVERYTHINGclassPost( SelfAwareModel ):   title = models.CharField()   blog  = models.ForeignKey( Blog )   body  = models.TextField()   slug  = models.SlugField()   likers = models.ForeignKey( User )   likes = models.IntegerField()@permalinkdef get_absolute_url( self ):      ...>>>  post = Post.objects.latest()>>>  obj.get_ct()>>>  <ContentType: post>
SELF AWARE EVERYTHINGclassPost( SelfAwareModel ):   title = models.CharField()   blog  = models.ForeignKey( Blog )   body  = models.TextField()   slug  = models.SlugField()   likers = models.ForeignKey( User )   likes = models.IntegerField()@permalinkdef get_absolute_url( self ):      ...I KNOW MYCONTENT TYPE>>>  post = Post.objects.latest()>>>  obj.get_ct()>>>  <ContentType: post>
HOORAY!
PATTERN #2REAL Generic Views
REAL GENERIC VIEWdefobject_list( request, ct_id ... ):  type     = ContentType.objects.get( pk = ct_id )  model    = type.model_class()  obj_list = model._default_manager.all()return render_to_response( ... )
REAL GENERIC VIEWdefobject_detail( request, ct_id, obj_id, template=None ):  type     = ContentType.objects.get( pk = ct_id )  model    = type.model_class()  obj      = model._default_manager.get( pk = ct_id )if template isNone:     template = '%s_detail.html'%(type)return render_to_response( template )
REAL GENERIC VIEWdefobject_detail( request, ct_id, obj_id, template=None ):  type     = ContentType.objects.get( pk = ct_id )  model    = type.model_class()  obj      = model._default_manager.get( pk = ct_id )if template isNone:     template = '%s_detail.html'%(type)return render_to_response( template )
REAL GENERIC VIEWdefobject_detail( request, ct_id, obj_id, template=None ):  type     = ContentType.objects.get( pk = ct_id )  model    = type.model_class()  obj      = model._default_manager.get( pk = ct_id )if template isNone:     template = '%s_detail.html'%(type)return render_to_response( template )Might Want To Cache That
REAL GENERIC VIEWdefobject_detail( request, ct_id, obj_id, template=None ):  type     = ContentType.objects.get( pk = ct_id )  model    = type.model_class()  obj      = model._default_manager.get( pk = ct_id )if template isNone:     template = '%s_detail.html'%(type)return render_to_response( template )Might Want To Cache Thatself.__class__._cache[self.db][key]
cPickle & noSQL DB ( Redis )REAL GENERIC VIEWproject|| - likeables/|| - blog/ |  |- templates/  |   |- blog/    |   -post_list.html    |   -post_detail.html | -urls.py|| - templates/|  - object_list.html|  - object_detail.html| - urls.py
MORE PROBLEMSBlogPostPost LikesPost Likers
MORE PROBLEMSBlogPostPost LikersPost Likes
LESS PROBLEMSLIKEContentTypePOSTANYTHINGFEATURE
LIKE ANYTHING YOU WANT
NOT BAD, KID!
PATTERN #3Universal URLs
UNIVERSAL URLsurlpatterns = patterns( 'myproj.myapp',    url(         r'^(?P<slug>[-\w]+)/(?P<ct_id>\d+)/list/$', 'object_list',name='my_proj_content_list'       ),    url(         r'^(?P<slug>[-\w]+)/(?P<ct_id>\d+)-(?P<obj_id>\d+)/$','object_detail',name="my_proj_content_detail"       ),    url(        r'^(?P<slug>[-\w]+)/(?P<ct_id>\d+)-(?P<obj_id>\d+)/edit/$',        'object_edit',name="my_proj_content_edit"       )   ...)
UNIVERSAL URLs/something-here/23/list//some-title/23-21//some-title/23-21/edit//some-title/23-21/delete//some-title/23-21/blah/
PATTERN #4Magic Forms
MAGIC FORMSdefedit_object( request, ct_id, obj_id ):   obj = utils.get_object( ct_id, obj_id )
MAGIC FORMSdefedit_object( request, ct_id, obj_id ):   obj = utils.get_object( ct_id, obj_id )   form = ???
MAGIC FORMSdefedit_object( request, ct_id, obj_id ):   obj = utils.get_object( ct_id, obj_id )   form = ???Can't predefine  ModelForm when you don't know what model you're working with
MAGIC FORMS
MAGIC FORMSdefform_class_for( obj, includes=[] excludes=[] ):   modelclass = obj.get_ct().model_class()class_MagicForm(forms.ModelForm):      ...classMeta:        model= modelclassif includes:          fields = includesif excludes:          exclude = excludes return _MagicForm
MAGIC FORMSdefform_class_for( obj, includes=[] excludes=[] ):   modelclass = obj.get_ct().model_class()class_MagicForm(forms.ModelForm):      ...classMeta:        model= modelclassif includes:          fields = includesif excludes:          exclude = excludes return _MagicFormDON'T KNOW
MAGIC FORMSdefform_class_for( obj, includes=[] excludes=[] ):   modelclass = obj.get_ct().model_class()class_MagicForm(forms.ModelForm):      ...classMeta:        model= modelclassif includes:          fields = includesif excludes:          exclude = excludes return _MagicFormDON'TCARE
MAGIC FORMSdefform_class_for( obj, includes=[] excludes=[] ):   modelclass = obj.get_ct().model_class()class_MagicForm(forms.ModelForm):      ...classMeta:        model= modelclassif includes:          fields = includesif excludes:          exclude = excludes return _MagicFormPERFECTLYLEGAL
FULL CIRCLEdefedit_object( request, ct_id, obj_id ):   obj = utils.get_object( ct_id, obj_id )   formclass = utils.get_form_for( obj )   form = formclass()return render_to_response( ... {'form':form} )
FULL CIRCLEdefedit_object( request, ct_id, obj_id ):   obj = utils.get_object( ct_id, obj_id )   formclass = utils.get_form_for( obj )   form = formclass()return render_to_response( ... {'form':form} )DON'T KNOW
FULL CIRCLEdefedit_object( request, ct_id, obj_id ):   obj = utils.get_object( ct_id, obj_id )   formclass = utils.get_form_for( obj )   form = formclass()return render_to_response( ... {'form':form} )DON'TCARE
DEAD SIMPLE{%urlmy_proj_content_list ct_id=obj.get_ct_id %}{%urlmy_proj_content_detail    slug=obj.slug, ct_id=obj.get_ct_id, obj_id=obj.pk %}{%urlmy_proj_content_edit    slug=obj.slug, ct_id=obj.get_ct_id, obj_id=obj.pk %}
FOR THE WIN
SCALE IT OUTDefine A ModelSync DBMake A Template ( Maybe ? )Rinse Repeate
PATTERNS RECAPSelf Aware Models

More Related Content

PDF
The Django Book, Chapter 16: django.contrib
PDF
Django design-patterns
PPTX
Django: Advanced Models
KEY
Django Pro ORM
KEY
Advanced Django ORM techniques
PDF
ORM in Django
PDF
Class-based views with Django
PPT
Patterns In-Javascript
The Django Book, Chapter 16: django.contrib
Django design-patterns
Django: Advanced Models
Django Pro ORM
Advanced Django ORM techniques
ORM in Django
Class-based views with Django
Patterns In-Javascript

What's hot (17)

PPTX
Javascript Common Design Patterns
PPTX
Introduction to Design Patterns in Javascript
PDF
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
PPTX
jQuery PPT
PPTX
Javascript Design Patterns
PDF
Django Patterns - Pycon India 2014
PDF
Template rendering in rails
PDF
KAAccessControl
PPTX
An Overview of Models in Django
PDF
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
PDF
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
PDF
GDG Addis - An Introduction to Django and App Engine
PDF
ERRest - The Next Steps
PDF
Entity api
PPTX
Art of Javascript
Javascript Common Design Patterns
Introduction to Design Patterns in Javascript
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
jQuery PPT
Javascript Design Patterns
Django Patterns - Pycon India 2014
Template rendering in rails
KAAccessControl
An Overview of Models in Django
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
GDG Addis - An Introduction to Django and App Engine
ERRest - The Next Steps
Entity api
Art of Javascript
Ad

Similar to Powerful Generic Patterns With Django (20)

PPTX
Meetup django common_problems(1)
ODP
Introduction to Django
PDF
Django workshop : let's make a blog
PPT
Mini Curso Django Ii Congresso Academico Ces
PDF
Django Good Practices
PDF
Ch9 .Best Practices for Class-Based Views
PPTX
Django tips and_tricks (1)
PPTX
The Django Web Application Framework 2
PPTX
The Django Web Application Framework 2
KEY
Jumpstart Django
PPTX
The Django Web Application Framework 2
PPTX
The Django Web Application Framework 2
PDF
Django Heresies
PDF
Introduction to Django
PDF
Gae Meets Django
PDF
Django class based views
ODP
Django tech-talk
PDF
Building Pluggable Web Applications using Django
PPT
Django Models
PDF
Rapid web application development using django - Part (1)
Meetup django common_problems(1)
Introduction to Django
Django workshop : let's make a blog
Mini Curso Django Ii Congresso Academico Ces
Django Good Practices
Ch9 .Best Practices for Class-Based Views
Django tips and_tricks (1)
The Django Web Application Framework 2
The Django Web Application Framework 2
Jumpstart Django
The Django Web Application Framework 2
The Django Web Application Framework 2
Django Heresies
Introduction to Django
Gae Meets Django
Django class based views
Django tech-talk
Building Pluggable Web Applications using Django
Django Models
Rapid web application development using django - Part (1)
Ad

Recently uploaded (20)

PPTX
James 1 Bible verses sermonbbbbbbbbbb.pptx
DOCX
Free Pomodoro Tecnique Effect Guide -25mint - pomodorotimer.com.au
PPTX
examinophobia;how does it occur and how to solve
PPTX
Hyperlipidemia current medication with lifestyle.
PDF
5 Popular Designs of Kashmir Silk Handmade Carpets.pdf
PPTX
Respiratory-and-Circulatory-Hazards-lecture.pptx
PPTX
Too Lucky to Be a Victim., an essay on social media
PDF
PrayerPetals- Where Faith and Womanhood Flourish Together.pdf
PDF
4 Mindset Shifts to Turn Frustration into Focus
PPTX
GEE2-BEED-II: Ibaloi Indigenous People .pptx
PPTX
PPT ARIEZ'S TOUR FINAL Pulogebang on.pptx
PDF
Economic and Financial Abuse - Hidden Tools of Power in Domestic Violence
PDF
Pranotsava Monsoon Retreat - Fazlani Nature's Nest
PPTX
The-World-of-Fashion-Trends-and-Innovation-2025.pptx
PDF
John Baptist Scalabrini Novena - Fr Luciano Final eddition.pdf
PDF
The Top Life Coach in Haarlem is Life Coach Rudolfo.pdf
PPTX
Expert Custom Tailoring Services for All Needs.pptx
PDF
The Lifestyle Benefits and Challenges of Living Alone
PPTX
hhhsyysvwvsydxuguduehshsvdhvdjbuwbjwjdbwubs
PDF
Non-Fatal Strangulation in Domestic Violence
James 1 Bible verses sermonbbbbbbbbbb.pptx
Free Pomodoro Tecnique Effect Guide -25mint - pomodorotimer.com.au
examinophobia;how does it occur and how to solve
Hyperlipidemia current medication with lifestyle.
5 Popular Designs of Kashmir Silk Handmade Carpets.pdf
Respiratory-and-Circulatory-Hazards-lecture.pptx
Too Lucky to Be a Victim., an essay on social media
PrayerPetals- Where Faith and Womanhood Flourish Together.pdf
4 Mindset Shifts to Turn Frustration into Focus
GEE2-BEED-II: Ibaloi Indigenous People .pptx
PPT ARIEZ'S TOUR FINAL Pulogebang on.pptx
Economic and Financial Abuse - Hidden Tools of Power in Domestic Violence
Pranotsava Monsoon Retreat - Fazlani Nature's Nest
The-World-of-Fashion-Trends-and-Innovation-2025.pptx
John Baptist Scalabrini Novena - Fr Luciano Final eddition.pdf
The Top Life Coach in Haarlem is Life Coach Rudolfo.pdf
Expert Custom Tailoring Services for All Needs.pptx
The Lifestyle Benefits and Challenges of Living Alone
hhhsyysvwvsydxuguduehshsvdhvdjbuwbjwjdbwubs
Non-Fatal Strangulation in Domestic Violence

Powerful Generic Patterns With Django

  • 2. POWERFUL GENERIC PATTERNSDjango's Content Types Framework
  • 3. CONTENTTYPESAn application that can track all of the models installed in your Django-powered project, providing a high-level, generic interface for working with your models
  • 5. CONTENTTYPES----------------------------------------| name | app_label | model || post | blogger | post || blog | blogger | Blog || like | likeable | Like |----------------------------------------
  • 6. PROBLEMblog = Blog.objects.get( pk = 1 )posts = Post.objects.filter( blog = blog )features = Post.objects.filter( feature = True )3+ URLs3+ view function3+ templates
  • 7. PROBLEMblog = Blog.objects.get( pk = 1 )posts = Post.objects.filter( blog = blog )features = Post.objects.filter( feature = True ){%for post in posts %}{{ post.title }} {{ post.like_set.count }} likes{%endfor%}
  • 9. GENERIC VIEWS?Take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to write too much code
  • 10. GENERIC VIEWS?from django.views.generic import list_detaildefmy_view( request ):return list_detail.object_list( queryset=Post.objects.all() )
  • 11. NOT SO GENERIC VIEWSfrom django.views.generic import list_detaildefmy_view( request ):return list_detail.object_list( queryset=Post.objects.all() )
  • 13. NOT SO GENERIC VIEWSTo Use A Generic View You Need...A Queryset
  • 15. A Model + Slug
  • 16. A Model + Slug FieldMORE PROBLEMSclassPost(models.Model): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField()BlogPostPost LikesPost Likers
  • 17. MORE PROBLEMSclassFeature(models.Model): title = models.CharField() post = models.ForeignKey( Post ) likers = models.ForeignKey( User ) likes = models.IntegerField()
  • 18. CONTENTTYPESAn application that can track all of the models installed in your Django-powered project, providing a high-level, generic interface for working with your models
  • 19. CONTENTTYPESUse the ORM without knowing what kind of objects you might be working with.
  • 20. CONTENTTYPESUse the ORM without knowing what kind of objects you might be working with. EVER.
  • 22. GENERIC FOREIGNKEYfrom django.contrib.contenttypes.models importContentTypefrom django.contrib.contenttypes importgenericclassFeature(models.Model): content_type = models.ForeignKey (ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type' ,'object_id' )
  • 23. MAGIC BITSclassFeature(models.Model): content_type = models.ForeignKey (ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( 'content_type' ,'object_id' )
  • 24. MAGIC BITSclassFeature(models.Model): content_type = models.ForeignKey (ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type' ,'object_id' )
  • 25. MAGIC BITSclassFeature(models.Model): content_type = models.ForeignKey (ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type' ,'object_id' )
  • 26. GENERIC FOREIGNKEY>>> obj = Feature.objects.get( pk = 1 )>>> obj.content_object>>> <Post: Hello World>>>> obj = Feature.objects.get( pk = 2 )>>> obj.content_object>>> <Blog: The Best Blog>>>> obj = Feature.objects.get( pk = 3 )>>> obj.content_object>>> <Anything: Whatever You Want>
  • 28. GENERIC FOREIGNKEYclassPost(models.Model): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField()classLike( models.Model ): content_type = models.ForeignKey( ContentType ) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( ... ) likers = models.ManyToMany( User )
  • 29. GOTCHA!Models are NOT aware of their Content Type
  • 30. MORE PROBLEMSclassLike( models.Model ): content_type = models.ForeignKey( ContentType ) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( ... ) likers = models.ManyToMany( User )
  • 31. MORE PROBLEMSclassLike( models.Model ): content_type = models.ForeignKey( ContentType ) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( ... ) likers = models.ManyToMany( User )deflike_view( request, object_id ): post = Post.objects.get( pk = object_id ) like = Like( object_id = post, ??? )
  • 32. GENERIC GEMSfrom django.contrib.contenttypes.models importContentTypefrom django.contrib.auth.models importUser>>> type = ContentType.objects.get_for_model( User )>>> type>>> <ContentType: user >>>> model = type.model_class()>>> model>>> <class: 'django.contrib.auth.models.User'>
  • 36. SELF AWARE MODELclassSelfAwareModel(models.Model): def get_ct( self ):''' Returns the Content Type for this instance'''return ContentType.objects.get_for_model(self)def get_ct_id( self ):''' Returns the id of the content type for this instance'''return self.get_ct().pkdef get_app_label( self ):return self.get_ct().app_labeldef get_model_name( self ):return self.get_ct().modelclassMeta: abstract = True
  • 37. SELF AWARE MODELclassSelfAwareModel(models.Model): def get_ct( self ):''' Returns the Content Type for this instance'''return ContentType.objects.get_for_model(self)def get_ct_id( self ):''' Returns the id of the content type for this instance'''return self.get_ct().pkdef get_app_label( self ):return self.get_ct().app_labeldef get_model_name( self ):return self.get_ct().modelclassMeta: abstract = TrueCACHED BY DJANGO
  • 38. SELF AWARE MODELclassSelfAwareModel(models.Model): def get_ct( self ):''' Returns the Content Type for this instance'''return ContentType.objects.get_for_model(self)def get_ct_id( self ):''' Returns the id of the content type for this instance'''return self.get_ct().pkdef get_app_label( self ):return self.get_ct().app_labeldef get_model_name( self ):return self.get_ct().modelclassMeta: abstract = TrueCACHED BY DJANGOself.__class__._cache[self.db][key]
  • 39. SELF AWARE EVERYTHINGclassPost( SelfAwareModel ): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField()
  • 40. SELF AWARE EVERYTHINGclassPost( SelfAwareModel ): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField()ALL MODELSSUBCLASSESELFAWAREMODEL
  • 41. SELF AWARE EVERYTHINGclassPost( SelfAwareModel ): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField()@permalinkdef get_absolute_url( self ): ...>>> post = Post.objects.latest()>>> obj.get_ct()>>> <ContentType: post>
  • 42. SELF AWARE EVERYTHINGclassPost( SelfAwareModel ): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField()@permalinkdef get_absolute_url( self ): ...I KNOW MYCONTENT TYPE>>> post = Post.objects.latest()>>> obj.get_ct()>>> <ContentType: post>
  • 45. REAL GENERIC VIEWdefobject_list( request, ct_id ... ): type = ContentType.objects.get( pk = ct_id ) model = type.model_class() obj_list = model._default_manager.all()return render_to_response( ... )
  • 46. REAL GENERIC VIEWdefobject_detail( request, ct_id, obj_id, template=None ): type = ContentType.objects.get( pk = ct_id ) model = type.model_class() obj = model._default_manager.get( pk = ct_id )if template isNone: template = '%s_detail.html'%(type)return render_to_response( template )
  • 47. REAL GENERIC VIEWdefobject_detail( request, ct_id, obj_id, template=None ): type = ContentType.objects.get( pk = ct_id ) model = type.model_class() obj = model._default_manager.get( pk = ct_id )if template isNone: template = '%s_detail.html'%(type)return render_to_response( template )
  • 48. REAL GENERIC VIEWdefobject_detail( request, ct_id, obj_id, template=None ): type = ContentType.objects.get( pk = ct_id ) model = type.model_class() obj = model._default_manager.get( pk = ct_id )if template isNone: template = '%s_detail.html'%(type)return render_to_response( template )Might Want To Cache That
  • 49. REAL GENERIC VIEWdefobject_detail( request, ct_id, obj_id, template=None ): type = ContentType.objects.get( pk = ct_id ) model = type.model_class() obj = model._default_manager.get( pk = ct_id )if template isNone: template = '%s_detail.html'%(type)return render_to_response( template )Might Want To Cache Thatself.__class__._cache[self.db][key]
  • 50. cPickle & noSQL DB ( Redis )REAL GENERIC VIEWproject|| - likeables/|| - blog/ | |- templates/ | |- blog/ | -post_list.html | -post_detail.html | -urls.py|| - templates/| - object_list.html| - object_detail.html| - urls.py
  • 57. UNIVERSAL URLsurlpatterns = patterns( 'myproj.myapp', url( r'^(?P<slug>[-\w]+)/(?P<ct_id>\d+)/list/$', 'object_list',name='my_proj_content_list' ), url( r'^(?P<slug>[-\w]+)/(?P<ct_id>\d+)-(?P<obj_id>\d+)/$','object_detail',name="my_proj_content_detail" ), url( r'^(?P<slug>[-\w]+)/(?P<ct_id>\d+)-(?P<obj_id>\d+)/edit/$', 'object_edit',name="my_proj_content_edit" ) ...)
  • 60. MAGIC FORMSdefedit_object( request, ct_id, obj_id ): obj = utils.get_object( ct_id, obj_id )
  • 61. MAGIC FORMSdefedit_object( request, ct_id, obj_id ): obj = utils.get_object( ct_id, obj_id ) form = ???
  • 62. MAGIC FORMSdefedit_object( request, ct_id, obj_id ): obj = utils.get_object( ct_id, obj_id ) form = ???Can't predefine ModelForm when you don't know what model you're working with
  • 64. MAGIC FORMSdefform_class_for( obj, includes=[] excludes=[] ): modelclass = obj.get_ct().model_class()class_MagicForm(forms.ModelForm): ...classMeta: model= modelclassif includes: fields = includesif excludes: exclude = excludes return _MagicForm
  • 65. MAGIC FORMSdefform_class_for( obj, includes=[] excludes=[] ): modelclass = obj.get_ct().model_class()class_MagicForm(forms.ModelForm): ...classMeta: model= modelclassif includes: fields = includesif excludes: exclude = excludes return _MagicFormDON'T KNOW
  • 66. MAGIC FORMSdefform_class_for( obj, includes=[] excludes=[] ): modelclass = obj.get_ct().model_class()class_MagicForm(forms.ModelForm): ...classMeta: model= modelclassif includes: fields = includesif excludes: exclude = excludes return _MagicFormDON'TCARE
  • 67. MAGIC FORMSdefform_class_for( obj, includes=[] excludes=[] ): modelclass = obj.get_ct().model_class()class_MagicForm(forms.ModelForm): ...classMeta: model= modelclassif includes: fields = includesif excludes: exclude = excludes return _MagicFormPERFECTLYLEGAL
  • 68. FULL CIRCLEdefedit_object( request, ct_id, obj_id ): obj = utils.get_object( ct_id, obj_id ) formclass = utils.get_form_for( obj ) form = formclass()return render_to_response( ... {'form':form} )
  • 69. FULL CIRCLEdefedit_object( request, ct_id, obj_id ): obj = utils.get_object( ct_id, obj_id ) formclass = utils.get_form_for( obj ) form = formclass()return render_to_response( ... {'form':form} )DON'T KNOW
  • 70. FULL CIRCLEdefedit_object( request, ct_id, obj_id ): obj = utils.get_object( ct_id, obj_id ) formclass = utils.get_form_for( obj ) form = formclass()return render_to_response( ... {'form':form} )DON'TCARE
  • 71. DEAD SIMPLE{%urlmy_proj_content_list ct_id=obj.get_ct_id %}{%urlmy_proj_content_detail slug=obj.slug, ct_id=obj.get_ct_id, obj_id=obj.pk %}{%urlmy_proj_content_edit slug=obj.slug, ct_id=obj.get_ct_id, obj_id=obj.pk %}
  • 73. SCALE IT OUTDefine A ModelSync DBMake A Template ( Maybe ? )Rinse Repeate
  • 75. Better Generic Views & utilities
  • 78. Better Generic Views & utilities
  • 80. Magic FormsYou can perform CRUD ops and create any kind of relationship on any kind of object at anytimewithout programming for every situation.
  • 81. FIN