SlideShare a Scribd company logo
POWERFUL GENERIC PATTERNS Django's Content Types Framework
CONTENTTYPES An 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    | ----------------------------------------
PROBLEM blog = Blog.objects.get( pk = 1 ) posts = Post.objects.filter( blog = blog ) features = Post.objects.filter( feature = True ) 3+ URLs 3+ view function 3+ templates
PROBLEM blog = 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_detail defmy_view( request ): return list_detail.object_list(               queryset=Post.objects.all()     )
NOT SO GENERIC VIEWS from django.views.generic import list_detail defmy_view( request ): return list_detail.object_list(               queryset=Post.objects.all()     )
NOT SO GENERIC VIEWS
NOT SO GENERIC VIEWS To Use A Generic View You Need... ,[object Object]
A Model + ID
A Model + Slug
A Model + Slug Field,[object Object]
MORE PROBLEMS classFeature(models.Model):    title = models.CharField()    post  = models.ForeignKey( Post )    likers = models.ForeignKey( User )    likes = models.IntegerField()
CONTENTTYPES An 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
CONTENTTYPES Use the ORM without knowing what kind of objects you might be working with.
CONTENTTYPES Use the ORM without knowing what kind of objects you might be working with.  EVER.
CONTENTTYPES Your Model ContentType Model A Model C Model B
GENERIC FOREIGNKEY from django.contrib.contenttypes.models importContentTypefrom django.contrib.contenttypes importgeneric classFeature(models.Model):    content_type = models.ForeignKey (ContentType)    object_id    = models.PositiveIntegerField()    content_object = generic.GenericForeignKey( 'content_type'                            ,'object_id'                                               )
MAGIC BITS classFeature(models.Model):    content_type = models.ForeignKey (ContentType)    object_id    = models.PositiveIntegerField()    content_object = generic.GenericForeignKey(    'content_type'                                            ,'object_id'                                               )
MAGIC BITS classFeature(models.Model):    content_type = models.ForeignKey (ContentType)    object_id    = models.PositiveIntegerField()    content_object = generic.GenericForeignKey( 'content_type'                                               ,'object_id'                                               )
MAGIC BITS classFeature(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 FOREIGNKEY classPost(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 PROBLEMS classLike( models.Model ):   content_type   = models.ForeignKey( ContentType )   object_id      = models.PositiveIntegerField()   content_object = generic.GenericForeignKey( ... )   likers         = models.ManyToMany( User )
MORE PROBLEMS classLike( 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 GEMS from django.contrib.contenttypes.models importContentType from 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 #1 Self-Aware Model
SELF AWARE MODEL classSelfAwareModel(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().pk def get_app_label( self ): return self.get_ct().app_label def get_model_name( self ): return self.get_ct().model classMeta:        abstract = True
SELF AWARE MODEL classSelfAwareModel(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().pk def get_app_label( self ): return self.get_ct().app_label def get_model_name( self ): return self.get_ct().model classMeta:        abstract = True CACHED BY DJANGO
SELF AWARE MODEL classSelfAwareModel(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().pk def get_app_label( self ): return self.get_ct().app_label def get_model_name( self ): return self.get_ct().model classMeta:        abstract = True CACHED BY DJANGO self.__class__._cache[self.db][key]
SELF AWARE EVERYTHING classPost( SelfAwareModel ):    title = models.CharField()    blog  = models.ForeignKey( Blog )    body  = models.TextField()    slug  = models.SlugField()    likers = models.ForeignKey( User )    likes = models.IntegerField()
SELF AWARE EVERYTHING classPost( SelfAwareModel ):    title = models.CharField()    blog  = models.ForeignKey( Blog )    body  = models.TextField()    slug  = models.SlugField()    likers = models.ForeignKey( User )    likes = models.IntegerField() ALL MODELS SUBCLASSE SELFAWAREMODEL
SELF AWARE EVERYTHING classPost( SelfAwareModel ):    title = models.CharField()    blog  = models.ForeignKey( Blog )    body  = models.TextField()    slug  = models.SlugField()    likers = models.ForeignKey( User )    likes = models.IntegerField() @permalink def get_absolute_url( self ):       ... >>>  post = Post.objects.latest() >>>  obj.get_ct() >>>  <ContentType: post>
SELF AWARE EVERYTHING classPost( SelfAwareModel ):    title = models.CharField()    blog  = models.ForeignKey( Blog )    body  = models.TextField()    slug  = models.SlugField()    likers = models.ForeignKey( User )    likes = models.IntegerField() @permalink def get_absolute_url( self ):       ... I KNOW MY CONTENT TYPE >>>  post = Post.objects.latest() >>>  obj.get_ct() >>>  <ContentType: post>
HOORAY!
PATTERN #2 REAL Generic Views
REAL GENERIC VIEW defobject_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 VIEW defobject_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 VIEW defobject_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 VIEW defobject_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 VIEW defobject_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 ,[object Object]
cPickle & noSQL DB ( Redis ),[object Object]
MORE PROBLEMS Blog Post Post Likes Post Likers
MORE PROBLEMS Blog Post Post Likers Post Likes
LESS PROBLEMS LIKE ContentType POST ANYTHING FEATURE
LIKE ANYTHING YOU WANT
NOT BAD, KID!
PATTERN #3 Universal URLs
UNIVERSAL URLs urlpatterns = patterns( 'myproj.myapp',     url(          r'^(?P<slug>[-]+)/(?P<ct_id>+)/list/$',  'object_list', name='my_proj_content_list'        ),     url(          r'^(?P<slug>[-]+)/(?P<ct_id>+)-(?P<obj_id>+)/$', 'object_detail', name="my_proj_content_detail"        ),     url(         r'^(?P<slug>[-]+)/(?P<ct_id>+)-(?P<obj_id>+)/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 #4 Magic Forms
MAGIC FORMS defedit_object( request, ct_id, obj_id ):    obj = utils.get_object( ct_id, obj_id )
MAGIC FORMS defedit_object( request, ct_id, obj_id ):    obj = utils.get_object( ct_id, obj_id )    form = ???
MAGIC FORMS defedit_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 FORMS defform_class_for( obj, includes=[] excludes=[] ):    modelclass = obj.get_ct().model_class() class_MagicForm(forms.ModelForm):       ... classMeta:         model= modelclass if includes:           fields = includes if excludes:           exclude = excludes  return _MagicForm
MAGIC FORMS defform_class_for( obj, includes=[] excludes=[] ):    modelclass = obj.get_ct().model_class() class_MagicForm(forms.ModelForm):       ... classMeta:         model= modelclass if includes:           fields = includes if excludes:           exclude = excludes  return _MagicForm DON'T KNOW
MAGIC FORMS defform_class_for( obj, includes=[] excludes=[] ):    modelclass = obj.get_ct().model_class() class_MagicForm(forms.ModelForm):       ... classMeta:         model= modelclass if includes:           fields = includes if excludes:           exclude = excludes  return _MagicForm DON'T CARE
MAGIC FORMS defform_class_for( obj, includes=[] excludes=[] ):    modelclass = obj.get_ct().model_class() class_MagicForm(forms.ModelForm):       ... classMeta:         model= modelclass if includes:           fields = includes if excludes:           exclude = excludes  return _MagicForm PERFECTLY LEGAL
FULL CIRCLE defedit_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 CIRCLE defedit_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 CIRCLE defedit_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 CARE
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 OUT Define A Model Sync DB Make A Template ( Maybe ? ) Rinse  Repeate
PATTERNS RECAP ,[object Object]

More Related Content

What's hot

Javascript Common Design Patterns
Javascript Common Design PatternsJavascript Common Design Patterns
Javascript Common Design Patterns
Pham Huy Tung
 
Introduction to Design Patterns in Javascript
Introduction to Design Patterns in JavascriptIntroduction to Design Patterns in Javascript
Introduction to Design Patterns in Javascript
Santhosh Kumar Srinivasan
 
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
جلسه هفتم پایتون برای هکر های قانونی دوره مقدماتی پاییز ۹۲
Mohammad Reza Kamalifard
 
jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
Dominic Arrojado
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
Iván Fernández Perea
 
Django Patterns - Pycon India 2014
Django Patterns - Pycon India 2014Django Patterns - Pycon India 2014
Django Patterns - Pycon India 2014
arunvr
 
Template rendering in rails
Template rendering in rails Template rendering in rails
Template rendering in rails
Hung Wu Lo
 
An Overview of Models in Django
An Overview of Models in DjangoAn Overview of Models in Django
An Overview of Models in Django
Michael Auritt
 
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونیاسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
اسلاید جلسه ۹ کلاس پایتون برای هکر های قانونی
Mohammad Reza Kamalifard
 
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
QA Lab: тестирование ПО. Станислав Шмидт: "Self-testing REST APIs with API Fi...
GeeksLab Odessa
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
ERRest - The Next Steps
ERRest - The Next StepsERRest - The Next Steps
ERRest - The Next Steps
WO Community
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
Tarek Yehia
 

What's hot (17)

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

Similar to Powerful Generic Patterns With Django

Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blog
Pierre Sudron
 
(An Extended) Beginners Guide to Object Orientation in PHP
(An Extended) Beginners Guide to Object Orientation in PHP(An Extended) Beginners Guide to Object Orientation in PHP
(An Extended) Beginners Guide to Object Orientation in PHP
Rick Ogden
 
Django tips and_tricks (1)
Django tips and_tricks (1)Django tips and_tricks (1)
Django tips and_tricks (1)
andymccurdy
 
PyCon APAC - Django Test Driven Development
PyCon APAC - Django Test Driven DevelopmentPyCon APAC - Django Test Driven Development
PyCon APAC - Django Test Driven Development
Tudor Munteanu
 
Data Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreData Migrations in the App Engine Datastore
Data Migrations in the App Engine Datastore
Ryan Morlok
 
Django tech-talk
Django tech-talkDjango tech-talk
Django tech-talk
dtdannen
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
Joaquim Rocha
 
Introduction Django
Introduction DjangoIntroduction Django
Introduction Django
Wade Austin
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Djangofool2nd
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
Simon Willison
 
django-sitecats 0.4.0 : Python Package Index
django-sitecats 0.4.0 : Python Package Indexdjango-sitecats 0.4.0 : Python Package Index
django-sitecats 0.4.0 : Python Package Index
flagrantlawsuit53
 
Building a Portfolio With Custom Post Types
Building a Portfolio With Custom Post TypesBuilding a Portfolio With Custom Post Types
Building a Portfolio With Custom Post TypesAlex Blackie
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
clammyhysteria698
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
clammyhysteria698
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
clammyhysteria698
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
somberfan2012
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
flagrantlawsuit53
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
ludicrousexcerp10
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
successfuloutdo12
 

Similar to Powerful Generic Patterns With Django (20)

Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
Django workshop : let's make a blog
Django workshop : let's make a blogDjango workshop : let's make a blog
Django workshop : let's make a blog
 
(An Extended) Beginners Guide to Object Orientation in PHP
(An Extended) Beginners Guide to Object Orientation in PHP(An Extended) Beginners Guide to Object Orientation in PHP
(An Extended) Beginners Guide to Object Orientation in PHP
 
Django tips and_tricks (1)
Django tips and_tricks (1)Django tips and_tricks (1)
Django tips and_tricks (1)
 
PyCon APAC - Django Test Driven Development
PyCon APAC - Django Test Driven DevelopmentPyCon APAC - Django Test Driven Development
PyCon APAC - Django Test Driven Development
 
Data Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreData Migrations in the App Engine Datastore
Data Migrations in the App Engine Datastore
 
Django tech-talk
Django tech-talkDjango tech-talk
Django tech-talk
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Introduction Django
Introduction DjangoIntroduction Django
Introduction Django
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Django
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
django-sitecats 0.4.0 : Python Package Index
django-sitecats 0.4.0 : Python Package Indexdjango-sitecats 0.4.0 : Python Package Index
django-sitecats 0.4.0 : Python Package Index
 
Building a Portfolio With Custom Post Types
Building a Portfolio With Custom Post TypesBuilding a Portfolio With Custom Post Types
Building a Portfolio With Custom Post Types
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 

Recently uploaded

Gujarat Details in Hindi for children's for presentation in school
Gujarat Details in Hindi for children's for presentation in schoolGujarat Details in Hindi for children's for presentation in school
Gujarat Details in Hindi for children's for presentation in school
shouryajoshi5
 
erevna-influencers-social-media-stin-ellada
erevna-influencers-social-media-stin-elladaerevna-influencers-social-media-stin-ellada
erevna-influencers-social-media-stin-ellada
rvlassopoulou
 
What To Do If Your Ring Is Too Big? Must Read
What To Do If Your Ring Is Too Big? Must ReadWhat To Do If Your Ring Is Too Big? Must Read
What To Do If Your Ring Is Too Big? Must Read
Andrews Jewelers
 
30 Manipulation Techniques to be a smart person in society (1).pdf
30 Manipulation Techniques to be a smart person in society (1).pdf30 Manipulation Techniques to be a smart person in society (1).pdf
30 Manipulation Techniques to be a smart person in society (1).pdf
minaserver6679
 
EXPERIENCE MONSTER BITES STREETWEAR APPAREL
EXPERIENCE MONSTER BITES STREETWEAR APPARELEXPERIENCE MONSTER BITES STREETWEAR APPAREL
EXPERIENCE MONSTER BITES STREETWEAR APPAREL
6ctbkfpdxz
 
Unique Wedding Bands For Women Who Want To Stand Out.pptx
Unique Wedding Bands For Women Who Want To Stand Out.pptxUnique Wedding Bands For Women Who Want To Stand Out.pptx
Unique Wedding Bands For Women Who Want To Stand Out.pptx
Andrews Jewelers
 
What Makes Candle Making The Ultimate Bachelorette Celebration
What Makes Candle Making The Ultimate Bachelorette CelebrationWhat Makes Candle Making The Ultimate Bachelorette Celebration
What Makes Candle Making The Ultimate Bachelorette Celebration
Wick & Pour
 
From Stress to Success How Oakland's Corporate Wellness Programs are Cultivat...
From Stress to Success How Oakland's Corporate Wellness Programs are Cultivat...From Stress to Success How Oakland's Corporate Wellness Programs are Cultivat...
From Stress to Success How Oakland's Corporate Wellness Programs are Cultivat...
Kitchen on Fire
 
La transidentité, un sujet qui fractionne les Français
La transidentité, un sujet qui fractionne les FrançaisLa transidentité, un sujet qui fractionne les Français
La transidentité, un sujet qui fractionne les Français
Ipsos France
 
Johnny Depp Long Hair: A Signature Look Through the Years
Johnny Depp Long Hair: A Signature Look Through the YearsJohnny Depp Long Hair: A Signature Look Through the Years
Johnny Depp Long Hair: A Signature Look Through the Years
greendigital
 

Recently uploaded (10)

Gujarat Details in Hindi for children's for presentation in school
Gujarat Details in Hindi for children's for presentation in schoolGujarat Details in Hindi for children's for presentation in school
Gujarat Details in Hindi for children's for presentation in school
 
erevna-influencers-social-media-stin-ellada
erevna-influencers-social-media-stin-elladaerevna-influencers-social-media-stin-ellada
erevna-influencers-social-media-stin-ellada
 
What To Do If Your Ring Is Too Big? Must Read
What To Do If Your Ring Is Too Big? Must ReadWhat To Do If Your Ring Is Too Big? Must Read
What To Do If Your Ring Is Too Big? Must Read
 
30 Manipulation Techniques to be a smart person in society (1).pdf
30 Manipulation Techniques to be a smart person in society (1).pdf30 Manipulation Techniques to be a smart person in society (1).pdf
30 Manipulation Techniques to be a smart person in society (1).pdf
 
EXPERIENCE MONSTER BITES STREETWEAR APPAREL
EXPERIENCE MONSTER BITES STREETWEAR APPARELEXPERIENCE MONSTER BITES STREETWEAR APPAREL
EXPERIENCE MONSTER BITES STREETWEAR APPAREL
 
Unique Wedding Bands For Women Who Want To Stand Out.pptx
Unique Wedding Bands For Women Who Want To Stand Out.pptxUnique Wedding Bands For Women Who Want To Stand Out.pptx
Unique Wedding Bands For Women Who Want To Stand Out.pptx
 
What Makes Candle Making The Ultimate Bachelorette Celebration
What Makes Candle Making The Ultimate Bachelorette CelebrationWhat Makes Candle Making The Ultimate Bachelorette Celebration
What Makes Candle Making The Ultimate Bachelorette Celebration
 
From Stress to Success How Oakland's Corporate Wellness Programs are Cultivat...
From Stress to Success How Oakland's Corporate Wellness Programs are Cultivat...From Stress to Success How Oakland's Corporate Wellness Programs are Cultivat...
From Stress to Success How Oakland's Corporate Wellness Programs are Cultivat...
 
La transidentité, un sujet qui fractionne les Français
La transidentité, un sujet qui fractionne les FrançaisLa transidentité, un sujet qui fractionne les Français
La transidentité, un sujet qui fractionne les Français
 
Johnny Depp Long Hair: A Signature Look Through the Years
Johnny Depp Long Hair: A Signature Look Through the YearsJohnny Depp Long Hair: A Signature Look Through the Years
Johnny Depp Long Hair: A Signature Look Through the Years
 

Powerful Generic Patterns With Django

  • 1.
  • 2. POWERFUL GENERIC PATTERNS Django's Content Types Framework
  • 3. CONTENTTYPES An 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. PROBLEM blog = Blog.objects.get( pk = 1 ) posts = Post.objects.filter( blog = blog ) features = Post.objects.filter( feature = True ) 3+ URLs 3+ view function 3+ templates
  • 7. PROBLEM blog = 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_detail defmy_view( request ): return list_detail.object_list( queryset=Post.objects.all() )
  • 11. NOT SO GENERIC VIEWS from django.views.generic import list_detail defmy_view( request ): return list_detail.object_list( queryset=Post.objects.all() )
  • 12. NOT SO GENERIC VIEWS
  • 13.
  • 15. A Model + Slug
  • 16.
  • 17. MORE PROBLEMS classFeature(models.Model): title = models.CharField() post = models.ForeignKey( Post ) likers = models.ForeignKey( User ) likes = models.IntegerField()
  • 18. CONTENTTYPES An 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. CONTENTTYPES Use the ORM without knowing what kind of objects you might be working with.
  • 20. CONTENTTYPES Use the ORM without knowing what kind of objects you might be working with. EVER.
  • 21. CONTENTTYPES Your Model ContentType Model A Model C Model B
  • 22. GENERIC FOREIGNKEY from django.contrib.contenttypes.models importContentTypefrom django.contrib.contenttypes importgeneric classFeature(models.Model): content_type = models.ForeignKey (ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( 'content_type' ,'object_id' )
  • 23. MAGIC BITS classFeature(models.Model): content_type = models.ForeignKey (ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( 'content_type' ,'object_id' )
  • 24. MAGIC BITS classFeature(models.Model): content_type = models.ForeignKey (ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( 'content_type' ,'object_id' )
  • 25. MAGIC BITS classFeature(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 FOREIGNKEY classPost(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 PROBLEMS classLike( models.Model ): content_type = models.ForeignKey( ContentType ) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey( ... ) likers = models.ManyToMany( User )
  • 31. MORE PROBLEMS classLike( 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 GEMS from django.contrib.contenttypes.models importContentType from 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 MODEL classSelfAwareModel(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().pk def get_app_label( self ): return self.get_ct().app_label def get_model_name( self ): return self.get_ct().model classMeta: abstract = True
  • 37. SELF AWARE MODEL classSelfAwareModel(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().pk def get_app_label( self ): return self.get_ct().app_label def get_model_name( self ): return self.get_ct().model classMeta: abstract = True CACHED BY DJANGO
  • 38. SELF AWARE MODEL classSelfAwareModel(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().pk def get_app_label( self ): return self.get_ct().app_label def get_model_name( self ): return self.get_ct().model classMeta: abstract = True CACHED BY DJANGO self.__class__._cache[self.db][key]
  • 39. SELF AWARE EVERYTHING classPost( SelfAwareModel ): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField()
  • 40. SELF AWARE EVERYTHING classPost( SelfAwareModel ): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField() ALL MODELS SUBCLASSE SELFAWAREMODEL
  • 41. SELF AWARE EVERYTHING classPost( SelfAwareModel ): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField() @permalink def get_absolute_url( self ): ... >>> post = Post.objects.latest() >>> obj.get_ct() >>> <ContentType: post>
  • 42. SELF AWARE EVERYTHING classPost( SelfAwareModel ): title = models.CharField() blog = models.ForeignKey( Blog ) body = models.TextField() slug = models.SlugField() likers = models.ForeignKey( User ) likes = models.IntegerField() @permalink def get_absolute_url( self ): ... I KNOW MY CONTENT TYPE >>> post = Post.objects.latest() >>> obj.get_ct() >>> <ContentType: post>
  • 44. PATTERN #2 REAL Generic Views
  • 45. REAL GENERIC VIEW defobject_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 VIEW defobject_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 VIEW defobject_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 VIEW defobject_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.
  • 50.
  • 51. MORE PROBLEMS Blog Post Post Likes Post Likers
  • 52. MORE PROBLEMS Blog Post Post Likers Post Likes
  • 53. LESS PROBLEMS LIKE ContentType POST ANYTHING FEATURE
  • 57. UNIVERSAL URLs urlpatterns = patterns( 'myproj.myapp', url( r'^(?P<slug>[-]+)/(?P<ct_id>+)/list/$', 'object_list', name='my_proj_content_list' ), url( r'^(?P<slug>[-]+)/(?P<ct_id>+)-(?P<obj_id>+)/$', 'object_detail', name="my_proj_content_detail" ), url( r'^(?P<slug>[-]+)/(?P<ct_id>+)-(?P<obj_id>+)/edit/$', 'object_edit', name="my_proj_content_edit" ) ... )
  • 58. 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/
  • 60. MAGIC FORMS defedit_object( request, ct_id, obj_id ): obj = utils.get_object( ct_id, obj_id )
  • 61. MAGIC FORMS defedit_object( request, ct_id, obj_id ): obj = utils.get_object( ct_id, obj_id ) form = ???
  • 62. MAGIC FORMS defedit_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 FORMS defform_class_for( obj, includes=[] excludes=[] ): modelclass = obj.get_ct().model_class() class_MagicForm(forms.ModelForm): ... classMeta: model= modelclass if includes: fields = includes if excludes: exclude = excludes return _MagicForm
  • 65. MAGIC FORMS defform_class_for( obj, includes=[] excludes=[] ): modelclass = obj.get_ct().model_class() class_MagicForm(forms.ModelForm): ... classMeta: model= modelclass if includes: fields = includes if excludes: exclude = excludes return _MagicForm DON'T KNOW
  • 66. MAGIC FORMS defform_class_for( obj, includes=[] excludes=[] ): modelclass = obj.get_ct().model_class() class_MagicForm(forms.ModelForm): ... classMeta: model= modelclass if includes: fields = includes if excludes: exclude = excludes return _MagicForm DON'T CARE
  • 67. MAGIC FORMS defform_class_for( obj, includes=[] excludes=[] ): modelclass = obj.get_ct().model_class() class_MagicForm(forms.ModelForm): ... classMeta: model= modelclass if includes: fields = includes if excludes: exclude = excludes return _MagicForm PERFECTLY LEGAL
  • 68. FULL CIRCLE defedit_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 CIRCLE defedit_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 CIRCLE defedit_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 CARE
  • 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 OUT Define A Model Sync DB Make A Template ( Maybe ? ) Rinse Repeate
  • 74.
  • 75. Better Generic Views & utilities
  • 77.
  • 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