5. Major changes Since 1.3
Packages
Major changesMajor changes
Packages
Since Notes
auth 1.5 Custom user model; get_profile() deprecated
formtools 1.4 Reimplemented with CBVs
staticďŹles 1.4 New {%  static  %} template tag
localďŹavor 1.5 Deprecated
markup 1.5 Deprecated
9. CSRF Protection
⢠CSRF: Cross-Site Request Forgery
⢠Prevention
⢠Use POST for state-changing processes
⢠Add a token to every POST form
⢠Only allow POST when the form has an
appropriate token value
10. django.contrib.csrf
⢠Depends on django.contrib.sessions
⢠Template tag {%  csrf_token  %}
⢠Middleware CsrfMiddleware
⢠Beware of its limitations!
⢠AJAX contents
⢠Donât use @csrf_exempt unless needed
11. django.contrib.sites
⢠Sharing a data base between multiple sites
⢠Site:A name and a domain
⢠A SITE_ID in settings.py
⢠The Site model
⢠Site.objects.get_current()
⢠The CurrentSiteManager
19. But How?
⢠A ContentType model
⢠post_syncdb.connect(update_contenttypes)
⢠GenericForeignKey needs two helping fields
⢠A ForeignKey to ContentType
⢠A ďŹeld to hold the primary key (usually a
PositiveIntegerField)
20. from  django.db  import  models
from  django.contrib.contenttypes  import  generic
class  Attachment(models.Model):
    attached_file  =  models.FileField(...)
    content_type  =  models.ForeignKey(
        'contenttypes.ContentType'
    )
    object_id  =  models.PositiveIntegerField()
    content_object  =  generic.GenericForeignKey(
        'content_type',  'object_id'
    )
    #  ...  blah  blah  blah  ...
21. from  django.db  import  models
from  django.contrib.contenttypes  import  generic
class  Attachment(models.Model):
    attached_file  =  models.FileField(...)
    content_type  =  models.ForeignKey(
        'contenttypes.ContentType'
    )
    object_id  =  models.PositiveIntegerField()
    content_object  =  generic.GenericForeignKey(
        'content_type',  'object_id'
    )
    #  ...  blah  blah  blah  ...
22. from  django.db  import  models
from  django.contrib.contenttypes  import  generic
class  Attachment(models.Model):
    attached_file  =  models.FileField(...)
    content_type  =  models.ForeignKey(
        'contenttypes.ContentType'
    )
    object_id  =  models.PositiveIntegerField()
    content_object  =  generic.GenericForeignKey(
        'content_type',  'object_id'
    )
    #  ...  blah  blah  blah  ...
23. from  django.db  import  models
from  django.contrib.contenttypes  import  generic
class  Attachment(models.Model):
    attached_file  =  models.FileField(...)
    content_type  =  models.ForeignKey(
        'contenttypes.ContentType'
    )
    object_id  =  models.PositiveIntegerField()
    content_object  =  generic.GenericForeignKey()
    #  ...  blah  blah  blah  ...
24. post_attachments  =  Attachment.objects.filter(
    content_object=BlogPost.objects.latest('id')
)
taget_user  =  User.objects.get(username='uranusjr')
message  =  Message.objects.filter(
    from_user=request.user,  to_user=taget_user
).latest('created_at')
message_attachment  =  Attachment.objects.filter(
    content_object=message
)
message_attachment.content_object  =  ...
message_attachment.save()
25. Caveats
⢠Not really a database ďŹeld
⢠Cannot filter (or exclude, get, etc.)
⢠Cannot aggregate
⢠Some annotations do work
⢠No automatic reverse
26. from  django.db  import  models
from  django.contrib.contenttypes  import  generic
class  BlogPost(models.Model):
    #  ...  blah  blah  blah  ...
    attachments  =  generic.GenericRelation(Attachment)
    #  ...  blah  blah  blah  ...
27. from  django.db  import  models
from  django.contrib.contenttypes  import  generic
class  BlogPost(models.Model):
    #  ...  blah  blah  blah  ...
    attachments  =  generic.GenericRelation(Attachment)
    #  ...  blah  blah  blah  ...
blog_post  =  BlogPost.objects.latest('id')
#  These  two  become  equivalent
Attachment.objects.filter(content_object=blog_post)
blog_post.attachments