Who is this fool?!<br />A little about me<br />
Graphic Art<br />Photography<br />Web Design<br />Django<br />VFX<br />JavaScript<br />Print Design<br />Software<br />Dig...
PERL & JavaScript<br />
Django = HotPileOfAwesome( yes=True )<br />Django.build_web_app( fast=True )<br />
Django.make_an_app()<br />>>> True<br />Django.log_in_user()<br />>>> True<br />Django.comment_on_my_model()<br />>>> True...
Django.make_a_thumbnail()<br />>>> Thumbnail?<br />Django.send_text_message()<br />>>> Email Exception: no such thing<br /...
I've Got an <br />app for that!<br />
Searching<br />
Searching<br />Find Stuff - Fast<br />
Searching<br />Find Stuff - Fast<br />( without crushing my DB )<br />
Haystack<br />haystacksearch.org<br />Djapian<br />code.google.com/p/djapian/<br />Sphinx<br />django-sphinx ( github )<br />
Django<br />MyModel.objects.filter( text__icontains='word' )OR MyModel.objects.filter( text__search='word' )<br />Problems...
slow
mysql
manual DB configs</li></li></ul><li>Haystack<br />classPostIndex( SearchIndex ):     <br />body = CharField(document = Tru...
Haystack<br />SearchQuerySet()<br />.filter( <br />SQ(field=True) <br />| SQ(field__relation="something") <br />~SQ(field=...
Xapian<br />classArticleIndexer( Indexer ):<br />fields = ['title','body']<br />tags = [<br />('title','title', 3),<br />(...
Xapian<br />fromdjapian.indexer import CompositeIndexer<br />flags = xapian.QueryParser.FLAG_PARTIAL| <br />xapian.QueryPa...
Haystack<br />Xapian<br />Index files<br />Class Based Index<br />Customize Text For Indexing<br />Link to Indexed Object<...
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</li></li></ul><li>REST API<br />
REST API<br />Exposing Your Data<br />
REST API<br />Exposing Your Data<br />( In a meaningful way )<br />
Django<br />defview_func( reqeuest, *args, **kwargs):    request.GET    request.POST    request.FILES<br />Problems:<br />...
Can't restrict access based on HTTP methods
Serialization is left up to you
Manual auth
Tons of URLs</li></li></ul><li>PISTON<br />bitbucket.org/jespern/django-piston<br />TASTYPIE<br />toastdriven.github.com/d...
Piston<br />classMyHandler( BaseHandler ):     <br />methods_allowed =( 'GET', 'PUT')     <br />model = MyModel     <br />...
Tastypie<br />classMyResource( ModelResource ):<br />fk_field = fields.ForiegnKey( OtherResource, 'fk_field' )  <br />clas...
Tastypie - Client Side<br />newRequest.JSONP({<br />url:'http://www.yoursite.com/api/resource'<br />,method:'get'<br />,da...
PISTON<br />TASTYPIE<br />Multiple Formats<br />Throttling<br />All HTTP Methods<br />Authentication<br />Arbitrary Data R...
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</li></li></ul><li>READY IN MINUTES<br />
DATABASE<br />
DJANGO-SOUTH<br />south.aeracode.org<br />QUERYSET-TRANSFORM<br />github.com/jbalogh/django-queryset-transform<br />DJANGO...
SOUTH<br />
SOUTH<br />Database Migrations<br />
DJANGO<br />$ python manage.py syncdb<br />
DJANGO<br />$ python manage.py syncdb<br />>>> You have a new Database!<br />
DJANGO<br />classMyModel( models.Model):<br />relation = models.ForiegnKey( Model2 )<br />
DJANGO<br />classMyModel( models.Model ):<br />relation = models.ForiegnKey( Model2 )<br />classMyModel( models.Model ):<b...
DJANGO<br />$ python manage.py syncdb<br />
DJANGO<br />$ python manage.py syncdb<br />>>> Sucks to be you!<br />
WTF?!<br />
DJANGO<br />$ python manage.py syncdb<br />>>> Sucks to be you!<br />Problem:<br /><ul><li>syncdb doesn't really sync your...
DJANGO<br />classMyModel( models.Model ):<br />relation = models.ForiegnKey( Model2 )<br />classMyModel( models.Model ):<b...
SOUTH<br />$ python manage.py schemamigration <yourapp><br />>>> Sweet, run migrate<br />
SOUTH<br />$ python manage.py migrate <yourapp><br />>>> Done.<br />
SOUTH<br />
QUERYSET-TRANSFORM<br />github.com/jbalogh/django-queryset-transform<br />( n + 1 )<br />
QUERYSET-TRANSFORM<br />{%for object in object_list %}<br />{%for object in object.things.all %}<br />{%if object.relation...
QUERYSET-TRANSFORM<br />deflookup_tags(item_qs):<br />item_pks = [item.pk for item in item_qs]<br />m2mfield = Item._meta....
QUERYSET-TRANSFORM<br />qs = Item.objects.filter(<br />name__contains = 'e'<br />).transform(lookup_tags)<br />
QUERYSET-TRANSFORM<br />from django.db import connection<br />len( connection.queries )<br />>>> 2<br />
DJANGO-SELECTREVERSE<br />code.google.com/p/django-selectreverse<br />
DJANGO-SELECTREVERSE<br />Tries prefetching on reverse relations<br />model_instance.other_model_set.all()<br />
CONTENT MANAGEMENT<br />
DJANGO-CMS<br />www.django-cms.org<br />WEBCUBE-CMS<br />www.webcubecms.com<br />SATCHMO<br />www.satchmoproject.com<br />
WEBCUBE-CMS<br />
WEBCUBE-CMS<br />Feature Complete<br />
WEBCUBE-CMS<br />Feature Complete<br />Robust & Flexible<br />
WEBCUBE-CMS<br />Feature Complete<br />Robust & Flexible<br />( Commercial License )<br />
$12,000<br />
$12,000<br />
+ $300 / mo<br />
WTF?!<br />
DJANGO-CMS<br />
PRO<br />CON<br /><ul><li>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</li></li></ul><li>SATCHMO<br />
SATCHMO<br />E-Commerce-y CMS<br />
Django Admin<br />
DJANGO-GRAPPELLI<br />code.google.com/p/django-grappelli<br />DJANGO-FILEBROWSE<br />code.google.com/p/django-filebrowser<...
GRAPPELLI<br />
GRAPPELLI<br />
GRAPPELLI<br />
FILEBROWSER<br />
FILEBROWSER<br />
FILEBROWSER<br />
FILEBROWSER<br />
ADMIN TOOLS<br />
ADMIN TOOLS<br />
ADMIN TOOLS<br />
Image Management<br />
DJANGO-IMAGEKIT<br />bitbucket.org/jdriscoll/django-imagekit<br />DJANGO-PHOTOLOGUE<br />code.google.com/p/django-photolog...
DJANGO<br />classMyModel( models.Model ):<br />image = models.ImageField(upload_to='/' )<br />
DJANGO<br />classMyModel( models.Model ):<br />image = models.ImageField( upload_to='/' )<br />thumb = models.ImageField( ...
Upcoming SlideShare
Loading in...5
×

Meetup django common_problems(1)

2,631

Published on

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

Published in: Technology, Art & Photos
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,631
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
43
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Meetup django common_problems(1)

  1. 1.
  2. 2. Who is this fool?!<br />A little about me<br />
  3. 3. Graphic Art<br />Photography<br />Web Design<br />Django<br />VFX<br />JavaScript<br />Print Design<br />Software<br />Digital Media<br />CSS<br />Python<br />Flash / Flex<br />
  4. 4.
  5. 5. PERL & JavaScript<br />
  6. 6.
  7. 7. Django = HotPileOfAwesome( yes=True )<br />Django.build_web_app( fast=True )<br />
  8. 8. Django.make_an_app()<br />>>> True<br />Django.log_in_user()<br />>>> True<br />Django.comment_on_my_model()<br />>>> True<br />Django.message_my_user(user='myuser')<br />>>> True<br />Django.send_emails( emails=['me@mail.com'] )<br />>>> True<br />Django.do_complex_SQL( please=True )<br />>>> No Problem!<br />
  9. 9. Django.make_a_thumbnail()<br />>>> Thumbnail?<br />Django.send_text_message()<br />>>> Email Exception: no such thing<br />Django.search_all_my_stuff()<br />>>> WTF?<br />Django.get_data_in_under_75_queries()<br />>>> Whoa...<br />Django.alter_table(model='MyModel')<br />>>> Let's not get crazy<br />Django.be_restful( now=True )<br />>>> you meanrequest.POST<br />
  10. 10. I've Got an <br />app for that!<br />
  11. 11. Searching<br />
  12. 12. Searching<br />Find Stuff - Fast<br />
  13. 13. Searching<br />Find Stuff - Fast<br />( without crushing my DB )<br />
  14. 14. Haystack<br />haystacksearch.org<br />Djapian<br />code.google.com/p/djapian/<br />Sphinx<br />django-sphinx ( github )<br />
  15. 15. Django<br />MyModel.objects.filter( text__icontains='word' )OR MyModel.objects.filter( text__search='word' )<br />Problems:<br /><ul><li>single model
  16. 16. slow
  17. 17. mysql
  18. 18. manual DB configs</li></li></ul><li>Haystack<br />classPostIndex( SearchIndex ): <br />body = CharField(document = True, model_attr = 'body') <br />title = CharField( model_attr = 'title') <br />author = CharField( model_attr = 'author__get_full_name')<br />text = CharField( use_template = True ) <br />defget_queryset( self ): <br />return Post.objects.all() <br />defprepare_url( self, obj ): <br />return obj.get_absolute_url() <br />site.register(Post, PostIndex) <br />
  19. 19. Haystack<br />SearchQuerySet()<br />.filter( <br />SQ(field=True) <br />| SQ(field__relation="something") <br />~SQ(field=False) <br />)<br />>>> [ <SearchResult>, <SearchResult>, <SearchResult> ]<br />
  20. 20. Xapian<br />classArticleIndexer( Indexer ):<br />fields = ['title','body']<br />tags = [<br />('title','title', 3),<br />('body', 'as_plain_text', 1)<br />]<br />space.add_index(Article, ArticleIndexer, attach_as='indexer')<br />
  21. 21. Xapian<br />fromdjapian.indexer import CompositeIndexer<br />flags = xapian.QueryParser.FLAG_PARTIAL| <br />xapian.QueryParser.FLAG_WILDCARD<br />indexers = [ Model_1.indexer, Model_2.indexer ]<br />comp = CompositeIndexer( *indexers )<br />s = comp.search( `a phrase` ).flags( flags )<br />>>> [ <hit:score=100>,<hit:score=98> ]<br />$ s[0].instance<br />>>> <ModelInstance:Model><br />
  22. 22. Haystack<br />Xapian<br />Index files<br />Class Based Index<br />Customize Text For Indexing<br />Link to Indexed Object<br />Index Fields, Methods & Relations<br />Stemming, Facetting, Highlighting, Spelling<br /><ul><li>Pluggable Architecture
  23. 23. Whole Word Matching
  24. 24. Loads all indexers
  25. 25. Multiple Index Hooks
  26. 26. Stored fields
  27. 27. Django-like Syntax
  28. 28. Templates & Tags
  29. 29. Views, Forms & Fields
  30. 30. Wildcard Matching
  31. 31. Partial word matching
  32. 32. Doesn't Load All indexers
  33. 33. Interactive shell
  34. 34. Close to the metal ( Control )
  35. 35. Watches Models for changes
  36. 36. Pre-index Filtering</li></li></ul><li>REST API<br />
  37. 37. REST API<br />Exposing Your Data<br />
  38. 38. REST API<br />Exposing Your Data<br />( In a meaningful way )<br />
  39. 39. Django<br />defview_func( reqeuest, *args, **kwargs): request.GET request.POST request.FILES<br />Problems:<br /><ul><li>PUT & DELETE not translated
  40. 40. Can't restrict access based on HTTP methods
  41. 41. Serialization is left up to you
  42. 42. Manual auth
  43. 43. Tons of URLs</li></li></ul><li>PISTON<br />bitbucket.org/jespern/django-piston<br />TASTYPIE<br />toastdriven.github.com/django-tastypie/<br />
  44. 44. Piston<br />classMyHandler( BaseHandler ): <br />methods_allowed =( 'GET', 'PUT') <br />model = MyModel <br />classMyOtherHandler( BaseHandler ): <br />methods_allowed =( 'GET', 'PUT') <br />model = MyOtherModel<br />fields = ('title','content',('author',('username',) ) )<br />exclude = ('id', re.compile(r'^private_'))<br />defread( self, request):<br />return [ x for x in MyOtherModel.objects.select_related() ]<br />defupdate( self, request ):<br />...<br />
  45. 45. Tastypie<br />classMyResource( ModelResource ):<br />fk_field = fields.ForiegnKey( OtherResource, 'fk_field' ) <br />classMeta:<br />authentication = ApiKeyAuthentication() <br />queryset = MyModel.object.all()<br />resource_name = 'resource'<br />fields = ['title', 'content', ]<br />allowed_methods = [ 'get' ]<br />filtering = {<br />'somfield': ('exact', 'startswith')<br />}<br />defdehydrate_FOO( self, bundle ):<br />return bundle.data[ 'FOO' ] = 'What I want'<br />
  46. 46. Tastypie - Client Side<br />newRequest.JSONP({<br />url:'http://www.yoursite.com/api/resource'<br />,method:'get'<br />,data:{<br />username:'billyblanks'<br />,api_key:'5eb63bbbe01eeed093cb22bb8f5acdc3'<br />,title__startswith:"Hello World"<br />}<br />,onSuccess: function( data ){<br />console.info( data.meta );<br />console.log( data.objects ):<br />}).send();<br />http://www.yoursite.com/api/resource/1<br />http://www.yoursite.com/api/resource/set/1;5<br />http://www.yoursite.com/api/resource/?format=xml<br />
  47. 47. PISTON<br />TASTYPIE<br />Multiple Formats<br />Throttling<br />All HTTP Methods<br />Authentication<br />Arbitrary Data Resources<br />Highly Configurable<br /><ul><li>Django-like
  48. 48. Built in fields
  49. 49. Auto Meta Data
  50. 50. Resource URIs
  51. 51. ORM ablities ( client )
  52. 52. API Key Auth
  53. 53. Object Caching ( backends )
  54. 54. De / Re hydrations hooks
  55. 55. Validation Via Forms
  56. 56. Deep ORM Ties
  57. 57. Data Streaming
  58. 58. OAuth / contrib Auth
  59. 59. URI Templates
  60. 60. Auto API Docs</li></li></ul><li>READY IN MINUTES<br />
  61. 61. DATABASE<br />
  62. 62. DJANGO-SOUTH<br />south.aeracode.org<br />QUERYSET-TRANSFORM<br />github.com/jbalogh/django-queryset-transform<br />DJANGO-SELECTREVERSE<br />code.google.com/p/django-selectreverse<br />
  63. 63. SOUTH<br />
  64. 64. SOUTH<br />Database Migrations<br />
  65. 65. DJANGO<br />$ python manage.py syncdb<br />
  66. 66. DJANGO<br />$ python manage.py syncdb<br />>>> You have a new Database!<br />
  67. 67. DJANGO<br />classMyModel( models.Model):<br />relation = models.ForiegnKey( Model2 )<br />
  68. 68. DJANGO<br />classMyModel( models.Model ):<br />relation = models.ForiegnKey( Model2 )<br />classMyModel( models.Model ):<br />relation = models.ManyToMany( Model2 )<br />
  69. 69. DJANGO<br />$ python manage.py syncdb<br />
  70. 70. DJANGO<br />$ python manage.py syncdb<br />>>> Sucks to be you!<br />
  71. 71. WTF?!<br />
  72. 72. DJANGO<br />$ python manage.py syncdb<br />>>> Sucks to be you!<br />Problem:<br /><ul><li>syncdb doesn't really sync your db. Migrations must be done manually.For everyedatabase / set up.</li></li></ul><li>SOUTH<br /><ul><li>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</li></li></ul><li>DJANGO<br />classMyModel( models.Model ):<br />relation = models.ForiegnKey( Model2 )<br />classMyModel( models.Model ):<br />relation = models.ManyToMany( Model2 )<br />
  73. 73. DJANGO<br />classMyModel( models.Model ):<br />relation = models.ForiegnKey( Model2 )<br />classMyModel( models.Model ):<br />relation = models.ManyToMany( Model2 )<br />
  74. 74. SOUTH<br />$ python manage.py schemamigration <yourapp><br />>>> Sweet, run migrate<br />
  75. 75. SOUTH<br />$ python manage.py migrate <yourapp><br />>>> Done.<br />
  76. 76. SOUTH<br />
  77. 77. QUERYSET-TRANSFORM<br />github.com/jbalogh/django-queryset-transform<br />( n + 1 )<br />
  78. 78. QUERYSET-TRANSFORM<br />{%for object in object_list %}<br />{%for object in object.things.all %}<br />{%if object.relation %}<br />{{ object.relation.field.text }}<br />{%else%}<br />{{ object.other_relation }}<br />{%endif%}<br />{%endfor%}<br />{%empty%}<br />no soup for you<br />{%endfor%}<br />
  79. 79.
  80. 80. QUERYSET-TRANSFORM<br />deflookup_tags(item_qs):<br />item_pks = [item.pk for item in item_qs]<br />m2mfield = Item._meta.get_field_by_name('tags')[0]<br />tags_for_item = <br />Tag.objects.filter(<br />item__in = item_pks)<br />.extra(select = {'item_id': '%s.%s' % (<br />m2mfield.m2m_db_table(),<br />m2mfield.m2m_column_name()<br />) <br />}) <br />tag_dict = {}<br />for tag in tags_for_item:<br />tag_dict.setdefault(tag.item_id, []).append(tag)<br />for item in item_qs:<br />item.fetched_tags = tag_dict.get(item.pk, [])<br />
  81. 81. QUERYSET-TRANSFORM<br />qs = Item.objects.filter(<br />name__contains = 'e'<br />).transform(lookup_tags)<br />
  82. 82. QUERYSET-TRANSFORM<br />from django.db import connection<br />len( connection.queries )<br />>>> 2<br />
  83. 83. DJANGO-SELECTREVERSE<br />code.google.com/p/django-selectreverse<br />
  84. 84. DJANGO-SELECTREVERSE<br />Tries prefetching on reverse relations<br />model_instance.other_model_set.all()<br />
  85. 85. CONTENT MANAGEMENT<br />
  86. 86. DJANGO-CMS<br />www.django-cms.org<br />WEBCUBE-CMS<br />www.webcubecms.com<br />SATCHMO<br />www.satchmoproject.com<br />
  87. 87. WEBCUBE-CMS<br />
  88. 88. WEBCUBE-CMS<br />Feature Complete<br />
  89. 89. WEBCUBE-CMS<br />Feature Complete<br />Robust & Flexible<br />
  90. 90. WEBCUBE-CMS<br />Feature Complete<br />Robust & Flexible<br />( Commercial License )<br />
  91. 91. $12,000<br />
  92. 92. $12,000<br />
  93. 93.
  94. 94. + $300 / mo<br />
  95. 95. WTF?!<br />
  96. 96. DJANGO-CMS<br />
  97. 97.
  98. 98. PRO<br />CON<br /><ul><li>Heavily Customised Admin
  99. 99. Plugin Support
  100. 100. Template Switching
  101. 101. Menu Control
  102. 102. Translations
  103. 103. Front-End Editing ( latest )
  104. 104. Moderation
  105. 105. Template Tags
  106. 106. Lots of settings
  107. 107. Lots Of Settings ( again )
  108. 108. Another Learning Curve
  109. 109. Plone Paradox
  110. 110. Plugins a little wonky</li></li></ul><li>SATCHMO<br />
  111. 111. SATCHMO<br />E-Commerce-y CMS<br />
  112. 112. Django Admin<br />
  113. 113. DJANGO-GRAPPELLI<br />code.google.com/p/django-grappelli<br />DJANGO-FILEBROWSE<br />code.google.com/p/django-filebrowser<br />DJANGO-ADMIN TOOLS<br />bitbucket.org/izi/django-admin-tools<br />
  114. 114. GRAPPELLI<br />
  115. 115. GRAPPELLI<br />
  116. 116. GRAPPELLI<br />
  117. 117. FILEBROWSER<br />
  118. 118. FILEBROWSER<br />
  119. 119. FILEBROWSER<br />
  120. 120. FILEBROWSER<br />
  121. 121. ADMIN TOOLS<br />
  122. 122. ADMIN TOOLS<br />
  123. 123. ADMIN TOOLS<br />
  124. 124. Image Management<br />
  125. 125. DJANGO-IMAGEKIT<br />bitbucket.org/jdriscoll/django-imagekit<br />DJANGO-PHOTOLOGUE<br />code.google.com/p/django-photologue<br />SORL-THUMBNAIL<br />thumbnail.sorl.net/<br />
  126. 126. DJANGO<br />classMyModel( models.Model ):<br />image = models.ImageField(upload_to='/' )<br />
  127. 127. DJANGO<br />classMyModel( models.Model ):<br />image = models.ImageField( upload_to='/' )<br />thumb = models.ImageField( upload_to='/' )<br />
  128. 128. DJANGO<br />classMyModel( models.Model ):<br />image = models.ImageField( upload_to='/' )<br />thumb = models.ImageField( upload_to='/' )<br />>>> MyModel.objects.get(pk=1)<br />>>> MyModel.objects.image.url<br />>>> MyModel.objects.thumb.url<br />
  129. 129. ImageField<br />
  130. 130. ImageField<br />It Kinda Sucks<br />
  131. 131. IMAGEKIT<br />Evolution Of Photologue<br />
  132. 132. IMAGEKIT<br />classPhoto( ImageModel ):<br />name = models.CharField(max_length=100)<br />image = models.ImageField(upload_to='photos') <br />views = models.PositiveIntegerField(default=0)<br />classIKOptions:<br />#define the ImageKit options<br />spec_module = 'myapp.specs'<br />cache_dir = 'photos'<br />image_field = 'image'<br />save_count_as = 'views'<br />
  133. 133. IMAGEKIT<br />classResizeThumb( processors.Resize ):<br />width = 100<br />height = 75<br />crop = True<br />classResizeDisplay( processors.Resize ):<br />width = 600<br /># now we can define our thumbnail spec<br />classThumbnail( ImageSpec ):<br />access_as = 'thumbnail_image'<br />pre_cache = True<br />processors = [ ResizeThumb ]<br />classDisplay( ImageSpec ):<br />increment_count = True<br />processors = [ ResizeDisplay ]<br />
  134. 134. IMAGEKIT<br />$ photo = Photo.objects.get( pk =1 )<br />$ photo.display.url<br />>>> u'/path/to/media/photo_display.jpg'<br />$ photo.thumbnail.width<br />>>> 100<br />
  135. 135. IMAGEKIT<br />PHOTLOGUE<br />Caching<br />Template Friendly<br />Highly Configurable<br />Management Commands<br /><ul><li>Only 1 Model
  136. 136. DB Friendly
  137. 137. Format Adjustment
  138. 138. Color Adjustment
  139. 139. Transposing
  140. 140. Galleries out of the box
  141. 141. Bulk Upload
  142. 142. Admin Integration
  143. 143. Pre-cache command
  144. 144. Very DB Dependant
  145. 145. 4 Models ( 2 Solid )
  146. 146. Templates / Views / Urls
  147. 147. Exif Support</li></li></ul><li>EXIF TAGS<br />ISSUE 153<br />( shameless plug )<br />
  148. 148. IMAGEKIT<br />PHOTLOGUE<br />Caching<br />Template Friendly<br />Highly Configurable<br />Management Commands<br /><ul><li>Only 1 Model
  149. 149. DB Friendly
  150. 150. Format Adjustment
  151. 151. Color Adjustment
  152. 152. Transposing
  153. 153. Galleries out of the box
  154. 154. Bulk Upload
  155. 155. Admin Integration
  156. 156. Pre-cache command
  157. 157. Very DB Dependant
  158. 158. 4 Models ( 2 Solid )
  159. 159. Exif Support</li></ul>Beware of View Counts<br />
  160. 160. ImageField<br />
  161. 161. ImageField<br />It's Kinda Messy<br />
  162. 162. SORL<br />
  163. 163. SORL<br />from sorl.thumbnail import ImageField<br />classMyModel( models.Model ):<br />iamge = ImageField( upload_to="/folder" )<br />
  164. 164. SORL<br />{% load thumbnail %}<br />{%thumbnail obj.image "1000x600" crop='top' as im %}<br /><img src="{{ im.url }}" /><br />{%endthumbnail%}<br />
  165. 165. MESSAGING<br />
  166. 166. User - to - User<br />Messaging<br />
  167. 167. DJANGO-POSTMAN<br />bitbucket.org/psam/django-postman<br />DJANGO-MESSAGES<br />code.google.com/p/django-messages<br />DJANGO-SMS<br />code.google.com/p/django-sms<br />
  168. 168. DJANGO-SMS<br />
  169. 169. DJANGO-SMS<br />User Enters Phone #<br />User Selects Carrier<br />
  170. 170. THATS IT<br />
  171. 171. FREE<br />
  172. 172. UTILS<br />
  173. 173. DJANGO-EXTENSIONS<br />github.com/django-extensions/django-extensions<br />DEBUG-TOOLBAR<br />github.com/robhudson/django-debug-toolbar<br />DJANGO-MAINTENANCEMODE<br />pypi.python.org/pypi/django-maintenancemode<br />DJANGO-PAGINATION<br />github.com/ericflo/django-pagination<br />DJANGO-GUARDIAN<br />github.com/lukaszb/django-guardian<br />HOTSAUCE<br />( self plug )<br />
  174. 174. DJANGO-EXTENSIONS<br />21 Commands<br />4 Fields<br />2 Models<br />1 Admin Extension ( FK AutoComplete )<br />$ python manage.py dumpscript<br />>>> your_app.py<br />$ python manage.py runscript<br />>>> your_app.pyc<br />$ python manage.py runserver_plus<br />>>> Debugger baked right in<br />$ python manage.py shell_plus<br />>>> AutoLoad Models<br />$ python manage.py show_urls<br />>>> /your/endpoint/:idproject.app.views.view_func<br />
  175. 175. RUNSERVER_PLUS<br />
  176. 176. DEBUG TOOLBAR<br />
  177. 177. DEBUG TOOLBAR<br />
  178. 178. MAINTENANCEMODE<br />
  179. 179. MAINTENANCEMODE<br />MAINTENANCE_MODE = True<br />
  180. 180. MAINTENANCEMODE<br />MAINTENANCE_MODE = True<br />
  181. 181. MAINTENANCEMODE<br />MAINTENANCE_MODE = True<br />
  182. 182. HOTSAUCE<br />
  183. 183. HOTSAUCE<br />I Put That $*!T On Everything<br />
  184. 184. HOTSAUCE<br />
  185. 185. HOTSAUCE<br />
  186. 186. HOTSAUCE<br />QueueItem<br />ChangeSet<br />title<br />content<br />Model A<br />ChangeSet<br />title<br />content<br />ChangeSet<br />Model A<br />ChangeSet<br />title<br />content<br />
  187. 187. HOTSAUCE<br />
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×