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

Powerful Generic Patterns With Django

  • 2.
    POWERFUL GENERIC PATTERNSDjango'sContent Types Framework
  • 3.
    CONTENTTYPESAn application thatcan track all of the models installed in your Django-powered project, providing a high-level, generic interface for working with your models
  • 4.
  • 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%}
  • 8.
  • 9.
    GENERIC VIEWS?Take certaincommon 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.genericimport list_detaildefmy_view( request ):return list_detail.object_list( queryset=Post.objects.all() )
  • 11.
    NOT SO GENERICVIEWSfrom django.views.generic import list_detaildefmy_view( request ):return list_detail.object_list( queryset=Post.objects.all() )
  • 12.
  • 13.
    NOT SO GENERICVIEWSTo Use A Generic View You Need...A Queryset
  • 14.
  • 15.
  • 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 thatcan 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 ORMwithout knowing what kind of objects you might be working with.
  • 20.
    CONTENTTYPESUse the ORMwithout knowing what kind of objects you might be working with. EVER.
  • 21.
  • 22.
    GENERIC FOREIGNKEYfrom django.contrib.contenttypes.modelsimportContentTypefrom 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>
  • 27.
  • 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 NOTaware 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.modelsimportContentTypefrom 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'>
  • 33.
  • 34.
  • 35.
  • 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>
  • 43.
  • 44.
  • 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 & noSQLDB ( 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
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 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" ) ...)
  • 58.
  • 59.
  • 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
  • 63.
  • 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 %}
  • 72.
  • 73.
    SCALE IT OUTDefineA ModelSync DBMake A Template ( Maybe ? )Rinse Repeate
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
    Magic FormsYou canperform CRUD ops and create any kind of relationship on any kind of object at anytimewithout programming for every situation.
  • 81.