Meetup django common_problems(1)
Upcoming SlideShare
Loading in...5
×
 

Meetup django common_problems(1)

on

  • 2,789 views

Slides from 5/11/2011 Milwaukee Django User Group Meetup

Slides from 5/11/2011 Milwaukee Django User Group Meetup

Statistics

Views

Total Views
2,789
Views on SlideShare
2,789
Embed Views
0

Actions

Likes
5
Downloads
39
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Meetup django common_problems(1) Meetup django common_problems(1) Presentation Transcript

  • Who is this fool?!
    A little about me
  • Graphic Art
    Photography
    Web Design
    Django
    VFX
    JavaScript
    Print Design
    Software
    Digital Media
    CSS
    Python
    Flash / Flex
  • PERL & JavaScript
  • Django = HotPileOfAwesome( yes=True )
    Django.build_web_app( fast=True )
  • Django.make_an_app()
    >>> True
    Django.log_in_user()
    >>> True
    Django.comment_on_my_model()
    >>> True
    Django.message_my_user(user='myuser')
    >>> True
    Django.send_emails( emails=['me@mail.com'] )
    >>> True
    Django.do_complex_SQL( please=True )
    >>> No Problem!
  • Django.make_a_thumbnail()
    >>> Thumbnail?
    Django.send_text_message()
    >>> Email Exception: no such thing
    Django.search_all_my_stuff()
    >>> WTF?
    Django.get_data_in_under_75_queries()
    >>> Whoa...
    Django.alter_table(model='MyModel')
    >>> Let's not get crazy
    Django.be_restful( now=True )
    >>> you meanrequest.POST
  • I've Got an
    app for that!
  • Searching
  • Searching
    Find Stuff - Fast
  • Searching
    Find Stuff - Fast
    ( without crushing my DB )
  • Haystack
    haystacksearch.org
    Djapian
    code.google.com/p/djapian/
    Sphinx
    django-sphinx ( github )
  • Django
    MyModel.objects.filter( text__icontains='word' )OR MyModel.objects.filter( text__search='word' )
    Problems:
    • single model
    • slow
    • mysql
    • manual DB configs
  • Haystack
    classPostIndex( SearchIndex ):
    body = CharField(document = True, model_attr = 'body')
    title = CharField( model_attr = 'title')
    author = CharField( model_attr = 'author__get_full_name')
    text = CharField( use_template = True )
    defget_queryset( self ):
    return Post.objects.all()
    defprepare_url( self, obj ):
    return obj.get_absolute_url()
    site.register(Post, PostIndex)
  • Haystack
    SearchQuerySet()
    .filter(
    SQ(field=True)
    | SQ(field__relation="something")
    ~SQ(field=False)
    )
    >>> [ <SearchResult>, <SearchResult>, <SearchResult> ]
  • Xapian
    classArticleIndexer( Indexer ):
    fields = ['title','body']
    tags = [
    ('title','title', 3),
    ('body', 'as_plain_text', 1)
    ]
    space.add_index(Article, ArticleIndexer, attach_as='indexer')
  • Xapian
    fromdjapian.indexer import CompositeIndexer
    flags = xapian.QueryParser.FLAG_PARTIAL|
    xapian.QueryParser.FLAG_WILDCARD
    indexers = [ Model_1.indexer, Model_2.indexer ]
    comp = CompositeIndexer( *indexers )
    s = comp.search( `a phrase` ).flags( flags )
    >>> [ <hit:score=100>,<hit:score=98> ]
    $ s[0].instance
    >>> <ModelInstance:Model>
  • Haystack
    Xapian
    Index files
    Class Based Index
    Customize Text For Indexing
    Link to Indexed Object
    Index Fields, Methods & Relations
    Stemming, Facetting, Highlighting, Spelling
    • Pluggable Architecture
    • Whole Word Matching
    • Loads all indexers
    • Multiple Index Hooks
    • Stored fields
    • Django-like Syntax
    • Templates & Tags
    • Views, Forms & Fields
    • Wildcard Matching
    • Partial word matching
    • Doesn't Load All indexers
    • Interactive shell
    • Close to the metal ( Control )
    • Watches Models for changes
    • Pre-index Filtering
  • REST API
  • REST API
    Exposing Your Data
  • REST API
    Exposing Your Data
    ( In a meaningful way )
  • Django
    defview_func( reqeuest, *args, **kwargs): request.GET request.POST request.FILES
    Problems:
    • PUT & DELETE not translated
    • Can't restrict access based on HTTP methods
    • Serialization is left up to you
    • Manual auth
    • Tons of URLs
  • PISTON
    bitbucket.org/jespern/django-piston
    TASTYPIE
    toastdriven.github.com/django-tastypie/
  • Piston
    classMyHandler( BaseHandler ):
    methods_allowed =( 'GET', 'PUT')
    model = MyModel
    classMyOtherHandler( BaseHandler ):
    methods_allowed =( 'GET', 'PUT')
    model = MyOtherModel
    fields = ('title','content',('author',('username',) ) )
    exclude = ('id', re.compile(r'^private_'))
    defread( self, request):
    return [ x for x in MyOtherModel.objects.select_related() ]
    defupdate( self, request ):
    ...
  • Tastypie
    classMyResource( ModelResource ):
    fk_field = fields.ForiegnKey( OtherResource, 'fk_field' )
    classMeta:
    authentication = ApiKeyAuthentication()
    queryset = MyModel.object.all()
    resource_name = 'resource'
    fields = ['title', 'content', ]
    allowed_methods = [ 'get' ]
    filtering = {
    'somfield': ('exact', 'startswith')
    }
    defdehydrate_FOO( self, bundle ):
    return bundle.data[ 'FOO' ] = 'What I want'
  • Tastypie - Client Side
    newRequest.JSONP({
    url:'http://www.yoursite.com/api/resource'
    ,method:'get'
    ,data:{
    username:'billyblanks'
    ,api_key:'5eb63bbbe01eeed093cb22bb8f5acdc3'
    ,title__startswith:"Hello World"
    }
    ,onSuccess: function( data ){
    console.info( data.meta );
    console.log( data.objects ):
    }).send();
    http://www.yoursite.com/api/resource/1
    http://www.yoursite.com/api/resource/set/1;5
    http://www.yoursite.com/api/resource/?format=xml
  • PISTON
    TASTYPIE
    Multiple Formats
    Throttling
    All HTTP Methods
    Authentication
    Arbitrary Data Resources
    Highly Configurable
    • Django-like
    • Built in fields
    • Auto Meta Data
    • Resource URIs
    • ORM ablities ( client )
    • API Key Auth
    • Object Caching ( backends )
    • De / Re hydrations hooks
    • Validation Via Forms
    • Deep ORM Ties
    • Data Streaming
    • OAuth / contrib Auth
    • URI Templates
    • Auto API Docs
  • READY IN MINUTES
  • DATABASE
  • DJANGO-SOUTH
    south.aeracode.org
    QUERYSET-TRANSFORM
    github.com/jbalogh/django-queryset-transform
    DJANGO-SELECTREVERSE
    code.google.com/p/django-selectreverse
  • SOUTH
  • SOUTH
    Database Migrations
  • DJANGO
    $ python manage.py syncdb
  • DJANGO
    $ python manage.py syncdb
    >>> You have a new Database!
  • DJANGO
    classMyModel( models.Model):
    relation = models.ForiegnKey( Model2 )
  • DJANGO
    classMyModel( models.Model ):
    relation = models.ForiegnKey( Model2 )
    classMyModel( models.Model ):
    relation = models.ManyToMany( Model2 )
  • DJANGO
    $ python manage.py syncdb
  • DJANGO
    $ python manage.py syncdb
    >>> Sucks to be you!
  • WTF?!
  • DJANGO
    $ python manage.py syncdb
    >>> Sucks to be you!
    Problem:
    • syncdb doesn't really sync your db. Migrations must be done manually.For everyedatabase / set up.
  • SOUTH
    • Migrations are a set of sequential .py filesdb agnosticHandle most relation typesRolls migrations forward Handles Dependancies / Reverse DependanciesCan convert existing apps Overrides existing syncdb command
  • DJANGO
    classMyModel( models.Model ):
    relation = models.ForiegnKey( Model2 )
    classMyModel( models.Model ):
    relation = models.ManyToMany( Model2 )
  • DJANGO
    classMyModel( models.Model ):
    relation = models.ForiegnKey( Model2 )
    classMyModel( models.Model ):
    relation = models.ManyToMany( Model2 )
  • SOUTH
    $ python manage.py schemamigration <yourapp>
    >>> Sweet, run migrate
  • SOUTH
    $ python manage.py migrate <yourapp>
    >>> Done.
  • SOUTH
  • QUERYSET-TRANSFORM
    github.com/jbalogh/django-queryset-transform
    ( n + 1 )
  • QUERYSET-TRANSFORM
    {%for object in object_list %}
    {%for object in object.things.all %}
    {%if object.relation %}
    {{ object.relation.field.text }}
    {%else%}
    {{ object.other_relation }}
    {%endif%}
    {%endfor%}
    {%empty%}
    no soup for you
    {%endfor%}
  • QUERYSET-TRANSFORM
    deflookup_tags(item_qs):
    item_pks = [item.pk for item in item_qs]
    m2mfield = Item._meta.get_field_by_name('tags')[0]
    tags_for_item =
    Tag.objects.filter(
    item__in = item_pks)
    .extra(select = {'item_id': '%s.%s' % (
    m2mfield.m2m_db_table(),
    m2mfield.m2m_column_name()
    )
    })
    tag_dict = {}
    for tag in tags_for_item:
    tag_dict.setdefault(tag.item_id, []).append(tag)
    for item in item_qs:
    item.fetched_tags = tag_dict.get(item.pk, [])
  • QUERYSET-TRANSFORM
    qs = Item.objects.filter(
    name__contains = 'e'
    ).transform(lookup_tags)
  • QUERYSET-TRANSFORM
    from django.db import connection
    len( connection.queries )
    >>> 2
  • DJANGO-SELECTREVERSE
    code.google.com/p/django-selectreverse
  • DJANGO-SELECTREVERSE
    Tries prefetching on reverse relations
    model_instance.other_model_set.all()
  • CONTENT MANAGEMENT
  • DJANGO-CMS
    www.django-cms.org
    WEBCUBE-CMS
    www.webcubecms.com
    SATCHMO
    www.satchmoproject.com
  • WEBCUBE-CMS
  • WEBCUBE-CMS
    Feature Complete
  • WEBCUBE-CMS
    Feature Complete
    Robust & Flexible
  • WEBCUBE-CMS
    Feature Complete
    Robust & Flexible
    ( Commercial License )
  • $12,000
  • $12,000
  • + $300 / mo
  • WTF?!
  • DJANGO-CMS
  • PRO
    CON
    • Heavily Customised Admin
    • Plugin Support
    • Template Switching
    • Menu Control
    • Translations
    • Front-End Editing ( latest )
    • Moderation
    • Template Tags
    • Lots of settings
    • Lots Of Settings ( again )
    • Another Learning Curve
    • Plone Paradox
    • Plugins a little wonky
  • SATCHMO
  • SATCHMO
    E-Commerce-y CMS
  • Django Admin
  • DJANGO-GRAPPELLI
    code.google.com/p/django-grappelli
    DJANGO-FILEBROWSE
    code.google.com/p/django-filebrowser
    DJANGO-ADMIN TOOLS
    bitbucket.org/izi/django-admin-tools
  • GRAPPELLI
  • GRAPPELLI
  • GRAPPELLI
  • FILEBROWSER
  • FILEBROWSER
  • FILEBROWSER
  • FILEBROWSER
  • ADMIN TOOLS
  • ADMIN TOOLS
  • ADMIN TOOLS
  • Image Management
  • DJANGO-IMAGEKIT
    bitbucket.org/jdriscoll/django-imagekit
    DJANGO-PHOTOLOGUE
    code.google.com/p/django-photologue
    SORL-THUMBNAIL
    thumbnail.sorl.net/
  • DJANGO
    classMyModel( models.Model ):
    image = models.ImageField(upload_to='/' )
  • DJANGO
    classMyModel( models.Model ):
    image = models.ImageField( upload_to='/' )
    thumb = models.ImageField( upload_to='/' )
  • DJANGO
    classMyModel( models.Model ):
    image = models.ImageField( upload_to='/' )
    thumb = models.ImageField( upload_to='/' )
    >>> MyModel.objects.get(pk=1)
    >>> MyModel.objects.image.url
    >>> MyModel.objects.thumb.url
  • ImageField
  • ImageField
    It Kinda Sucks
  • IMAGEKIT
    Evolution Of Photologue
  • IMAGEKIT
    classPhoto( ImageModel ):
    name = models.CharField(max_length=100)
    image = models.ImageField(upload_to='photos')
    views = models.PositiveIntegerField(default=0)
    classIKOptions:
    #define the ImageKit options
    spec_module = 'myapp.specs'
    cache_dir = 'photos'
    image_field = 'image'
    save_count_as = 'views'
  • IMAGEKIT
    classResizeThumb( processors.Resize ):
    width = 100
    height = 75
    crop = True
    classResizeDisplay( processors.Resize ):
    width = 600
    # now we can define our thumbnail spec
    classThumbnail( ImageSpec ):
    access_as = 'thumbnail_image'
    pre_cache = True
    processors = [ ResizeThumb ]
    classDisplay( ImageSpec ):
    increment_count = True
    processors = [ ResizeDisplay ]
  • IMAGEKIT
    $ photo = Photo.objects.get( pk =1 )
    $ photo.display.url
    >>> u'/path/to/media/photo_display.jpg'
    $ photo.thumbnail.width
    >>> 100
  • IMAGEKIT
    PHOTLOGUE
    Caching
    Template Friendly
    Highly Configurable
    Management Commands
    • Only 1 Model
    • DB Friendly
    • Format Adjustment
    • Color Adjustment
    • Transposing
    • Galleries out of the box
    • Bulk Upload
    • Admin Integration
    • Pre-cache command
    • Very DB Dependant
    • 4 Models ( 2 Solid )
    • Templates / Views / Urls
    • Exif Support
  • EXIF TAGS
    ISSUE 153
    ( shameless plug )
  • IMAGEKIT
    PHOTLOGUE
    Caching
    Template Friendly
    Highly Configurable
    Management Commands
    • Only 1 Model
    • DB Friendly
    • Format Adjustment
    • Color Adjustment
    • Transposing
    • Galleries out of the box
    • Bulk Upload
    • Admin Integration
    • Pre-cache command
    • Very DB Dependant
    • 4 Models ( 2 Solid )
    • Exif Support
    Beware of View Counts
  • ImageField
  • ImageField
    It's Kinda Messy
  • SORL
  • SORL
    from sorl.thumbnail import ImageField
    classMyModel( models.Model ):
    iamge = ImageField( upload_to="/folder" )
  • SORL
    {% load thumbnail %}
    {%thumbnail obj.image "1000x600" crop='top' as im %}
    <img src="{{ im.url }}" />
    {%endthumbnail%}
  • MESSAGING
  • User - to - User
    Messaging
  • DJANGO-POSTMAN
    bitbucket.org/psam/django-postman
    DJANGO-MESSAGES
    code.google.com/p/django-messages
    DJANGO-SMS
    code.google.com/p/django-sms
  • DJANGO-SMS
  • DJANGO-SMS
    User Enters Phone #
    User Selects Carrier
  • THATS IT
  • FREE
  • UTILS
  • DJANGO-EXTENSIONS
    github.com/django-extensions/django-extensions
    DEBUG-TOOLBAR
    github.com/robhudson/django-debug-toolbar
    DJANGO-MAINTENANCEMODE
    pypi.python.org/pypi/django-maintenancemode
    DJANGO-PAGINATION
    github.com/ericflo/django-pagination
    DJANGO-GUARDIAN
    github.com/lukaszb/django-guardian
    HOTSAUCE
    ( self plug )
  • DJANGO-EXTENSIONS
    21 Commands
    4 Fields
    2 Models
    1 Admin Extension ( FK AutoComplete )
    $ python manage.py dumpscript
    >>> your_app.py
    $ python manage.py runscript
    >>> your_app.pyc
    $ python manage.py runserver_plus
    >>> Debugger baked right in
    $ python manage.py shell_plus
    >>> AutoLoad Models
    $ python manage.py show_urls
    >>> /your/endpoint/:idproject.app.views.view_func
  • RUNSERVER_PLUS
  • DEBUG TOOLBAR
  • DEBUG TOOLBAR
  • MAINTENANCEMODE
  • MAINTENANCEMODE
    MAINTENANCE_MODE = True
  • MAINTENANCEMODE
    MAINTENANCE_MODE = True
  • MAINTENANCEMODE
    MAINTENANCE_MODE = True
  • HOTSAUCE
  • HOTSAUCE
    I Put That $*!T On Everything
  • HOTSAUCE
  • HOTSAUCE
  • HOTSAUCE
    QueueItem
    ChangeSet
    title
    content
    Model A
    ChangeSet
    title
    content
    ChangeSet
    Model A
    ChangeSet
    title
    content
  • HOTSAUCE