Our experience with Django, or 10 useful modules that make life easier

    Priceless experience with Django, or Django for blondes, brunettes and all-all-allFor the past 15 weeks, we have been actively working on the Stillion project, our first mainstream project written in Django. An interesting experience was gained that we would like to share with the community.
    The article, first of all, will be interesting to beginners in Django.

    Django Modules


    South is a mechanism for migrating schemas and data to the database for django, something without which it is impossible to live without joint development. Unfortunately, there is no full-time migration mechanism in Dzhang to track changes in the project database schema. To fill this gap, we used south, which proved to be on the good side, the main thing is to understand how it works, everything is perfectly described in the documentation . Rake: migrations can be rolled without fixtures, this must be used. Data migrations must be written by hand. If you use abnormal fields (for example, a WYSIWYG field) and then abandon them, the old migrations will not work (but they can be rewritten manually).


    An implementation of nested sets for django models. Adds appropriate fields, as well as methods for working with the tree. An indispensable thing for implementing hierarchical structures in a relational DBMS. To represent the trees in the admin panel used fein-cms.


    A set of useful utilities, such as view_to and ajax_request decorators or HttpResponseReload. Recommended to enhance code elegance.


    A module that displays a panel with debugging information. We were primarily interested in the SQL query log, which is supplemented by information about the source of the query, time, etc.


    Morphological analyzer integrable with Django. It is used to declens words that are stored in normal form (that is, it saves us from storing various forms of one word). He also knows how to put words in the plural:
    morph.pluralize_inflected_ru(u'ПОПУГАЙ', 38)
    >>> ПОПУГАЕВ
    Disadvantages - slow sqlite as a backend (there are faster alternatives to Shelve, CDB and Tokyo Cabinet, but we don’t like them), not all words are correctly processed, but this is rare.


    In order not to suffer from “March 18, 2011” we use pytils to work with Russian dates. The module, by the way, can transliterate Russian text and choose the correct case depending on the number, as well as pymorphy (though without a dictionary, you have to store 3 word forms in the template).


    Application for automatically creating thumbnails of images. It works on the basis of key-value storage (of course, the redis available from the box is used as a backend ). The backend does not store the thumbnails themselves (they are stored in files), but only meta-information (a schematic diagram of the module ).
    {% thumbnail image "100x100" crop="top" as im %}
    {% endthumbnail %}



    Gluing and minification of CSS and JS. In the config, sets of files for gluing are stored, in the template specify the name of the assembly and compress generates a minified version (YUI and CSSMin filters). You can extend the functionality with your filters. It supports a versioned file name, which is very convenient when setting the Expires header for a long time to come (manage.py syncompress will update the names and contents of minified files itself when laid out on production).


    A very useful application from the creators of DISQUS, which allows you to conveniently log errors to the database. Sentry catches exceptions (for example, Http404), saves them and provides a beautiful interface that shows the frequency of the error (including graphically). It is possible to collect errors from multiple servers. Review of Sentry on Habré


    The application helps to make admin dashboards useful. There is a built-in set of widgets, but it will not be difficult to write your own. You can also create a menu for your tasks, which will be available on all pages of the admin panel. Review of admin tools on Habr


    When we made comments, we decided that authorization through third-party services (VKontakte, Facebook, openid and others like them) would be the best option. This is very convenient for the user, since he does not need to invent and remember a lot of passwords from different resources. In order to do this quickly and simply, there is a Loginza service . We did not really like the interface and we implemented integration with the main services on our own.


    The publicauth module was taken as a basis , but it had to be thoroughly updated. The matter was not limited to adding integration with mail.ru and other Russian services. We added the “correct” verification of the openId providers signatures and made a fairly friendly two-click widget.

    Productivity Optimization

    In practice, one of django's weaknesses was ORM. It, like all ORMs, spawns a large number of requests and consumes a lot of memory when it retrieves data. Without caching, generating the main page took a few seconds. Of the possible optimization strategies, caching turned out to be the cheapest and most effective, since the database schema did not allow the use of regular tools, such as select_related.


    Block caching by timeout, available “out of the box”, did not suit us, since it did not provide a convenient way to flush the cache. Therefore, the following strategy was chosen: the cache lives indefinitely (TIMEOUT = 0), and one of the parts of the write key in the cache is the date of the last update of the main object. Dependent objects update the core using post_save signals. Thus, when changing an object, the name of the key for caching automatically changes, which allows you to see the most current data on the site. Redis is used as a cache backend with the allkeys-lru extrusion algorithm (cache keys that have not been used for a long time will be deleted when the maxmemory limit is reached). By the way, in the radish we also store user sessions in order to offload the database a bit more.

    Order by RAND ()

    In order not to load the database with a selection of random values ​​via .order_by ('?'), The following approach is used: the data that needs to be mixed is retrieved and cached (especially if the logic for selecting this data is not trivial and requires a large number of queries) in the form list of identifiers, and when issued random.shuffle () is applied to this list.
    Summary: cache wisely :-))

    In conclusion

    Django is a great framework with a lot of nice additions; when you use it, you understand that it was created for our convenience. Have a nice coding!
    Threat. Do you have familiar typesetters / front-end developers looking for work (permanent, in the office, Moscow)?

    Also popular now: