Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Powerful Generic Patterns With Django

11,146 views

Published on

A look into django's powerful content types framework and way to use in to reduce the complexity of large applications

Published in: Lifestyle, Business
  • ⇒⇒⇒WRITE-MY-PAPER.net ⇐⇐⇐ has really great writers to help you get the grades you need, they are fast and do great research. Support will always contact you if there is any confusion with the requirements of your paper so they can make sure you are getting exactly what you need.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • You might get some help from ⇒ www.HelpWriting.net ⇐ Success and best regards!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Powerful Generic Patterns With Django

  1. 1.
  2. 2. POWERFUL GENERIC PATTERNS<br />Django's Content Types Framework<br />
  3. 3. CONTENTTYPES<br />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<br />
  4. 4. SAY WHAT ?<br />
  5. 5. CONTENTTYPES<br />----------------------------------------<br />| name | app_label | model |<br />| post | blogger | post |<br />| blog | blogger | Blog |<br />| like | likeable | Like |<br />----------------------------------------<br />
  6. 6. PROBLEM<br />blog = Blog.objects.get( pk = 1 )<br />posts = Post.objects.filter( blog = blog )<br />features = Post.objects.filter( feature = True )<br />3+ URLs<br />3+ view function<br />3+ templates<br />
  7. 7. PROBLEM<br />blog = Blog.objects.get( pk = 1 )<br />posts = Post.objects.filter( blog = blog )<br />features = Post.objects.filter( feature = True )<br />{%for post in posts %}<br />{{ post.title }} {{ post.like_set.count }} likes<br />{%endfor%}<br />
  8. 8. GENERIC VIEWS?<br />
  9. 9. GENERIC VIEWS?<br />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<br />
  10. 10. GENERIC VIEWS?<br />from django.views.generic import list_detail<br />defmy_view( request ):<br />return list_detail.object_list( <br /> queryset=Post.objects.all()<br /> )<br />
  11. 11. NOT SO GENERIC VIEWS<br />from django.views.generic import list_detail<br />defmy_view( request ):<br />return list_detail.object_list( <br /> queryset=Post.objects.all()<br /> )<br />
  12. 12. NOT SO GENERIC VIEWS<br />
  13. 13. NOT SO GENERIC VIEWS<br />To Use A Generic View You Need...<br /><ul><li>A Queryset
  14. 14. A Model + ID
  15. 15. A Model + Slug
  16. 16. A Model + Slug Field</li></li></ul><li>MORE PROBLEMS<br />classPost(models.Model):<br /> title = models.CharField()<br /> blog = models.ForeignKey( Blog )<br /> body = models.TextField()<br /> slug = models.SlugField()<br /> likers = models.ForeignKey( User )<br /> likes = models.IntegerField()<br />Blog<br />Post<br />Post Likes<br />Post Likers<br />
  17. 17. MORE PROBLEMS<br />classFeature(models.Model):<br /> title = models.CharField()<br /> post = models.ForeignKey( Post )<br /> likers = models.ForeignKey( User )<br /> likes = models.IntegerField()<br />
  18. 18. CONTENTTYPES<br />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<br />
  19. 19. CONTENTTYPES<br />Use the ORM without knowing what kind of objects you might be working with. <br />
  20. 20. CONTENTTYPES<br />Use the ORM without knowing what kind of objects you might be working with. <br />EVER.<br />
  21. 21. CONTENTTYPES<br />Your Model<br />ContentType<br />Model A<br />Model C<br />Model B<br />
  22. 22. GENERIC FOREIGNKEY<br />from django.contrib.contenttypes.models importContentTypefrom django.contrib.contenttypes importgeneric<br />classFeature(models.Model):<br /> content_type = models.ForeignKey (ContentType)<br /> object_id = models.PositiveIntegerField()<br /> content_object = generic.GenericForeignKey(<br />'content_type'<br /> ,'object_id'<br /> )<br />
  23. 23. MAGIC BITS<br />classFeature(models.Model):<br /> content_type = models.ForeignKey (ContentType)<br /> object_id = models.PositiveIntegerField()<br /> content_object = generic.GenericForeignKey( <br />'content_type'<br /> ,'object_id'<br /> )<br />
  24. 24. MAGIC BITS<br />classFeature(models.Model):<br /> content_type = models.ForeignKey (ContentType)<br /> object_id = models.PositiveIntegerField()<br /> content_object = generic.GenericForeignKey(<br />'content_type'<br /> ,'object_id'<br /> )<br />
  25. 25. MAGIC BITS<br />classFeature(models.Model):<br /> content_type = models.ForeignKey (ContentType)<br /> object_id = models.PositiveIntegerField()<br /> content_object = generic.GenericForeignKey(<br />'content_type'<br /> ,'object_id'<br /> )<br />
  26. 26. GENERIC FOREIGNKEY<br />>>> obj = Feature.objects.get( pk = 1 )<br />>>> obj.content_object<br />>>> <Post: Hello World><br />>>> obj = Feature.objects.get( pk = 2 )<br />>>> obj.content_object<br />>>> <Blog: The Best Blog><br />>>> obj = Feature.objects.get( pk = 3 )<br />>>> obj.content_object<br />>>> <Anything: Whatever You Want><br />
  27. 27. GENERIC FOREIGNKEY<br />
  28. 28. GENERIC FOREIGNKEY<br />classPost(models.Model):<br /> title = models.CharField()<br /> blog = models.ForeignKey( Blog )<br /> body = models.TextField()<br /> slug = models.SlugField()<br />classLike( models.Model ):<br /> content_type = models.ForeignKey( ContentType )<br /> object_id = models.PositiveIntegerField()<br /> content_object = generic.GenericForeignKey( ... )<br /> likers = models.ManyToMany( User )<br />
  29. 29. GOTCHA!<br />Models are NOT aware of their Content Type<br />
  30. 30. MORE PROBLEMS<br />classLike( models.Model ):<br /> content_type = models.ForeignKey( ContentType )<br /> object_id = models.PositiveIntegerField()<br /> content_object = generic.GenericForeignKey( ... )<br /> likers = models.ManyToMany( User )<br />
  31. 31. MORE PROBLEMS<br />classLike( models.Model ):<br /> content_type = models.ForeignKey( ContentType )<br /> object_id = models.PositiveIntegerField()<br /> content_object = generic.GenericForeignKey( ... )<br /> likers = models.ManyToMany( User )<br />deflike_view( request, object_id ):<br /> post = Post.objects.get( pk = object_id )<br /> like = Like( object_id = post, ??? )<br />
  32. 32. GENERIC GEMS<br />from django.contrib.contenttypes.models importContentType<br />from django.contrib.auth.models importUser<br />>>> type = ContentType.objects.get_for_model( User )<br />>>> type<br />>>> <ContentType: user ><br />>>> model = type.model_class()<br />>>> model<br />>>> <class: 'django.contrib.auth.models.User'><br />
  33. 33. GENERIC GEMS<br />
  34. 34. PATTERN #1<br />
  35. 35. PATTERN #1<br />Self-Aware Model<br />
  36. 36. SELF AWARE MODEL<br />classSelfAwareModel(models.Model): <br />def get_ct( self ):<br />''' Returns the Content Type for this instance'''<br />return ContentType.objects.get_for_model(self)<br />def get_ct_id( self ):<br />''' Returns the id of the content type for this instance'''<br />return self.get_ct().pk<br />def get_app_label( self ):<br />return self.get_ct().app_label<br />def get_model_name( self ):<br />return self.get_ct().model<br />classMeta:<br /> abstract = True<br />
  37. 37. SELF AWARE MODEL<br />classSelfAwareModel(models.Model): <br />def get_ct( self ):<br />''' Returns the Content Type for this instance'''<br />return ContentType.objects.get_for_model(self)<br />def get_ct_id( self ):<br />''' Returns the id of the content type for this instance'''<br />return self.get_ct().pk<br />def get_app_label( self ):<br />return self.get_ct().app_label<br />def get_model_name( self ):<br />return self.get_ct().model<br />classMeta:<br /> abstract = True<br />CACHED BY DJANGO<br />
  38. 38. SELF AWARE MODEL<br />classSelfAwareModel(models.Model): <br />def get_ct( self ):<br />''' Returns the Content Type for this instance'''<br />return ContentType.objects.get_for_model(self)<br />def get_ct_id( self ):<br />''' Returns the id of the content type for this instance'''<br />return self.get_ct().pk<br />def get_app_label( self ):<br />return self.get_ct().app_label<br />def get_model_name( self ):<br />return self.get_ct().model<br />classMeta:<br /> abstract = True<br />CACHED BY DJANGO<br />self.__class__._cache[self.db][key]<br />
  39. 39. SELF AWARE EVERYTHING<br />classPost( SelfAwareModel ):<br /> title = models.CharField()<br /> blog = models.ForeignKey( Blog )<br /> body = models.TextField()<br /> slug = models.SlugField()<br /> likers = models.ForeignKey( User )<br /> likes = models.IntegerField()<br />
  40. 40. SELF AWARE EVERYTHING<br />classPost( SelfAwareModel ):<br /> title = models.CharField()<br /> blog = models.ForeignKey( Blog )<br /> body = models.TextField()<br /> slug = models.SlugField()<br /> likers = models.ForeignKey( User )<br /> likes = models.IntegerField()<br />ALL MODELS<br />SUBCLASSE<br />SELFAWAREMODEL<br />
  41. 41. SELF AWARE EVERYTHING<br />classPost( SelfAwareModel ):<br /> title = models.CharField()<br /> blog = models.ForeignKey( Blog )<br /> body = models.TextField()<br /> slug = models.SlugField()<br /> likers = models.ForeignKey( User )<br /> likes = models.IntegerField()<br />@permalink<br />def get_absolute_url( self ):<br /> ...<br />>>> post = Post.objects.latest()<br />>>> obj.get_ct()<br />>>> <ContentType: post><br />
  42. 42. SELF AWARE EVERYTHING<br />classPost( SelfAwareModel ):<br /> title = models.CharField()<br /> blog = models.ForeignKey( Blog )<br /> body = models.TextField()<br /> slug = models.SlugField()<br /> likers = models.ForeignKey( User )<br /> likes = models.IntegerField()<br />@permalink<br />def get_absolute_url( self ):<br /> ...<br />I KNOW MY<br />CONTENT TYPE<br />>>> post = Post.objects.latest()<br />>>> obj.get_ct()<br />>>> <ContentType: post><br />
  43. 43. HOORAY!<br />
  44. 44. PATTERN #2<br />REAL Generic Views<br />
  45. 45. REAL GENERIC VIEW<br />defobject_list( request, ct_id ... ):<br /> type = ContentType.objects.get( pk = ct_id )<br /> model = type.model_class()<br /> obj_list = model._default_manager.all()<br />return render_to_response( ... )<br />
  46. 46. REAL GENERIC VIEW<br />defobject_detail( request, ct_id, obj_id, template=None ):<br /> type = ContentType.objects.get( pk = ct_id )<br /> model = type.model_class()<br /> obj = model._default_manager.get( pk = ct_id )<br />if template isNone:<br /> template = '%s_detail.html'%(type)<br />return render_to_response( template )<br />
  47. 47. REAL GENERIC VIEW<br />defobject_detail( request, ct_id, obj_id, template=None ):<br /> type = ContentType.objects.get( pk = ct_id )<br /> model = type.model_class()<br /> obj = model._default_manager.get( pk = ct_id )<br />if template isNone:<br /> template = '%s_detail.html'%(type)<br />return render_to_response( template )<br />
  48. 48. REAL GENERIC VIEW<br />defobject_detail( request, ct_id, obj_id, template=None ):<br /> type = ContentType.objects.get( pk = ct_id )<br /> model = type.model_class()<br /> obj = model._default_manager.get( pk = ct_id )<br />if template isNone:<br /> template = '%s_detail.html'%(type)<br />return render_to_response( template )<br />Might Want To Cache That<br />
  49. 49. REAL GENERIC VIEW<br />defobject_detail( request, ct_id, obj_id, template=None ):<br /> type = ContentType.objects.get( pk = ct_id )<br /> model = type.model_class()<br /> obj = model._default_manager.get( pk = ct_id )<br />if template isNone:<br /> template = '%s_detail.html'%(type)<br />return render_to_response( template )<br />Might Want To Cache That<br /><ul><li>self.__class__._cache[self.db][key]
  50. 50. cPickle & noSQL DB ( Redis )</li></li></ul><li>REAL GENERIC VIEW<br />project<br />|<br />| - likeables/<br />|<br />| - blog/<br /> |<br /> |- templates/<br /> |<br /> |- blog/<br /> | -post_list.html<br /> | -post_detail.html<br /> | -urls.py<br />|<br />| - templates/<br />| - object_list.html<br />| - object_detail.html<br />| - urls.py<br />
  51. 51. MORE PROBLEMS<br />Blog<br />Post<br />Post Likes<br />Post Likers<br />
  52. 52. MORE PROBLEMS<br />Blog<br />Post<br />Post Likers<br />Post Likes<br />
  53. 53. LESS PROBLEMS<br />LIKE<br />ContentType<br />POST<br />ANYTHING<br />FEATURE<br />
  54. 54. LIKE ANYTHING YOU WANT<br />
  55. 55. NOT BAD, KID!<br />
  56. 56. PATTERN #3<br />Universal URLs<br />
  57. 57. UNIVERSAL URLs<br />urlpatterns = patterns( 'myproj.myapp',<br /> url(<br /> r'^(?P<slug>[-w]+)/(?P<ct_id>d+)/list/$', <br />'object_list',<br />name='my_proj_content_list'<br /> ),<br /> url(<br /> r'^(?P<slug>[-w]+)/(?P<ct_id>d+)-(?P<obj_id>d+)/$',<br />'object_detail',<br />name="my_proj_content_detail"<br /> ),<br /> url(<br /> r'^(?P<slug>[-w]+)/(?P<ct_id>d+)-(?P<obj_id>d+)/edit/$',<br /> 'object_edit',<br />name="my_proj_content_edit"<br /> )<br /> ...<br />)<br />
  58. 58. UNIVERSAL URLs<br />/something-here/23/list/<br />/some-title/23-21/<br />/some-title/23-21/edit/<br />/some-title/23-21/delete/<br />/some-title/23-21/blah/<br />
  59. 59. PATTERN #4<br />Magic Forms<br />
  60. 60. MAGIC FORMS<br />defedit_object( request, ct_id, obj_id ):<br /> obj = utils.get_object( ct_id, obj_id )<br />
  61. 61. MAGIC FORMS<br />defedit_object( request, ct_id, obj_id ):<br /> obj = utils.get_object( ct_id, obj_id )<br /> form = ???<br />
  62. 62. MAGIC FORMS<br />defedit_object( request, ct_id, obj_id ):<br /> obj = utils.get_object( ct_id, obj_id )<br /> form = ???<br />Can't predefine ModelForm when you don't know what model you're working with<br />
  63. 63. MAGIC FORMS<br />
  64. 64. MAGIC FORMS<br />defform_class_for( obj, includes=[] excludes=[] ):<br /> modelclass = obj.get_ct().model_class()<br />class_MagicForm(forms.ModelForm):<br /> ...<br />classMeta:<br /> model= modelclass<br />if includes:<br /> fields = includes<br />if excludes:<br /> exclude = excludes <br />return _MagicForm<br />
  65. 65. MAGIC FORMS<br />defform_class_for( obj, includes=[] excludes=[] ):<br /> modelclass = obj.get_ct().model_class()<br />class_MagicForm(forms.ModelForm):<br /> ...<br />classMeta:<br /> model= modelclass<br />if includes:<br /> fields = includes<br />if excludes:<br /> exclude = excludes <br />return _MagicForm<br />DON'T KNOW<br />
  66. 66. MAGIC FORMS<br />defform_class_for( obj, includes=[] excludes=[] ):<br /> modelclass = obj.get_ct().model_class()<br />class_MagicForm(forms.ModelForm):<br /> ...<br />classMeta:<br /> model= modelclass<br />if includes:<br /> fields = includes<br />if excludes:<br /> exclude = excludes <br />return _MagicForm<br />DON'T<br />CARE <br />
  67. 67. MAGIC FORMS<br />defform_class_for( obj, includes=[] excludes=[] ):<br /> modelclass = obj.get_ct().model_class()<br />class_MagicForm(forms.ModelForm):<br /> ...<br />classMeta:<br /> model= modelclass<br />if includes:<br /> fields = includes<br />if excludes:<br /> exclude = excludes <br />return _MagicForm<br />PERFECTLY<br />LEGAL<br />
  68. 68. FULL CIRCLE<br />defedit_object( request, ct_id, obj_id ):<br /> obj = utils.get_object( ct_id, obj_id )<br /> formclass = utils.get_form_for( obj )<br /> form = formclass()<br />return render_to_response( ... {'form':form} )<br />
  69. 69. FULL CIRCLE<br />defedit_object( request, ct_id, obj_id ):<br /> obj = utils.get_object( ct_id, obj_id )<br /> formclass = utils.get_form_for( obj )<br /> form = formclass()<br />return render_to_response( ... {'form':form} )<br />DON'T KNOW<br />
  70. 70. FULL CIRCLE<br />defedit_object( request, ct_id, obj_id ):<br /> obj = utils.get_object( ct_id, obj_id )<br /> formclass = utils.get_form_for( obj )<br /> form = formclass()<br />return render_to_response( ... {'form':form} )<br />DON'T<br />CARE <br />
  71. 71. DEAD SIMPLE<br />{%urlmy_proj_content_list ct_id=obj.get_ct_id %}<br />{%urlmy_proj_content_detail<br /> slug=obj.slug, ct_id=obj.get_ct_id, obj_id=obj.pk %}<br />{%urlmy_proj_content_edit<br /> slug=obj.slug, ct_id=obj.get_ct_id, obj_id=obj.pk %}<br />
  72. 72. FOR THE WIN<br />
  73. 73. SCALE IT OUT<br />Define A Model<br />Sync DB<br />Make A Template ( Maybe ? )<br />Rinse <br />Repeate<br />
  74. 74. PATTERNS RECAP<br /><ul><li>Self Aware Models
  75. 75. Better Generic Views & utilities
  76. 76. Universial URLs
  77. 77. Magic Forms</li></li></ul><li>PATTERNS RECAP<br /><ul><li>Self Aware Models
  78. 78. Better Generic Views & utilities
  79. 79. Universial URLs
  80. 80. Magic Forms</li></ul>You can perform CRUD ops and create any kind of relationship on any kind of object at anytimewithout programming for every situation.<br />
  81. 81. FIN<br />

×