Hacker News new | comments | show | ask | jobs | submit login
My essential django package list (spapas.github.io)
190 points by spapas82 9 days ago | hide | past | web | 70 comments | favorite





Django packages are often awwwwwfully tempting but the more of them you use the more likely things are to start acting weird (they don't all play nicely together) and the more pain you're going to have upgrading Django versions. IRS really important to assess whether you really need all the complexity any add-on brings.

This also leafs me to favour more stay-out-of-my-way add one like django-silk over django-debug-toolbar


I have a different philosophy. If some functionality is offered by a good-quality (supported, good docs etc) django package then go on and use it. If you want to be DRY you shouldn't re-implement functionality that others have already implemented. Also, after you use a package you more or less learn it and it's easy to re-use it in your next project -- while if you implement your own solution you'll most probably need to resort to horrendous copy and paste from your old project to your new one to re-use it!

Also, as I already mention in my article, if you use a package and you use it for its intented purpose you have a quick reference for some of your project's functionality (f.e if you use django-waffle then you'll know that some parts of the project can be enabled or disabled at will) - if instead you had implemented everything yourself you (or the person that needs to understand your project) would need to read everything to know what's happening. So, for me, using a good django package does not add but actually removes complexity from your project!

I can't remember any package incompatibilities - instead as I already mention in my article there are a lot of packages that work great together (django-tables with django-filter, django-rest-framework with django-filter, django-taggit with django-autocomplete-light etc).

Finally, I partially agree with your comment about more pain when upgrading django versions however considering that

- supported projects are usually upgraded a little after a new version of django is out (most of them are already prepared before the new django version is out since they can be tested using the beta version)

- django keeps supporting (non LTS) old versions for 8 months (and 16 months for securiy fixes) so in this time most probably all your dependecies will have updated so as to support the new django version

- all packages are open source so you can contribute to help move to the next version

the upgrading pain should be very little... When I upgraded from django 1.10 to 1.11 I also upgraded all the packages I describe in the list and everything worked without problems!


Cool.

My "always on" Django apps:

  * django-compressor
  * django-debug-toolbar
  * django-waffle
  * django-jenkins
  * django-statsd-mozilla
  * django-markwhat
  * django-storages (to put static assets on S3/Cloudfront)
  * django-smoketest
Frequent additions as needed:

  * django-bootstrap3
  * django-rest-framework
  * django-filter
  * celery
  * wagtail
I used to use django-extensions everywhere, but it pulls in ipython and all of ipython's dependencies, which gets pretty heavy.

Interesting list - we have a lot in common (however I prefer rq vs celery because of ease of installation and configuration)

For django-extensions are you sure about ipython? I install it with pip install django-extensions and nothing else is installed. Ipython will be used if found, if not it will fallback to the default python shell (it also supports bpython and ptpython: http://django-extensions.readthedocs.io/en/latest/shell_plus...).

I wasn't aware of django-smoketest - seems like a nice addition to my deploy workflow!


Is it actually worth using shell_plus without ipython though?

If I was starting from scratch, I'd take a closer look at django-rq. I've used celery for years though and have more experience running RabbitMQ than Redis, so it's the devil I know.

I wrote django-smoketest originally, so I'm a bit biased, but I can't count how many problems it's caught for me early on. A related blog post I wrote last year: https://compiled.ctl.columbia.edu/articles/smoketesting-for-...


For me yes, using shell_plus even with the plain old python shell is worth it because it automagically imports most of the things you are going to need and saves you a lot of keystrokes (it imports all your models and some things from django, most notably settings so you don't need to do a 'from django.conf import settings'). Also, as I have already mentioned in the article, the killer feature of django-extensions (for me) is the runserver_plus and its integration with the Werkzeug debugger - just add an exception somewhere in your app and you'll get a full python shell.

I would definitely consider (and probably use) celery for an application with heavy task usage (or if I had the need for its more advanced capabilities) - definitely using a proper message queue like RabbitMQ should have better behavior than Redis, however django-rq covers all my needs till now so that's what I have included in the list and use in my day to day projects. After all, redis is much more popular than RabbitMQ and can be used for other purposes beyond asynchronous tasks (for example you can use redis for caching instead of memcached and also django-constance uses redis to save settings).

Thanks for the article, it confirms that django-smoketest is something I need use to my new proejcts and probably integrate it to old projects with a lot of moving parts!


Would love to know your thoughts on wagtail? I've been evaluating it (as against django cms mostly), but resources seem generally scarce - there's no big irc channel, the mailing list directs you to SO, and SO doesn't seem particularly active on the wagtail front either. So where do you go for help or if you need to bounce something off someone more experienced in Wagtail than yourself?

Streamfield looks great! It seems a perfect replacement to my rigid model-per-content-type approach.

Wagtail's deviation from standard Django patterns (no views!) are a little concerning too.


I'm one of the Wagtail core developers. We made the mistake of spreading our support across too many channels (Google Groups, Stack Overflow, IRC, semi-private Slack) but we've made a clear decision to focus on Stack Overflow for developer-related questions:

https://stackoverflow.com/questions/tagged/wagtail

mainly as a result of this poll:

https://twitter.com/WagtailCMS/status/801384753589080064

Please feel free to contact me directly (details in profile) if you're not getting the support you need on SO.


Yeah, Wagtail documentation is a bit scattered. That's probably one of the larger issues I've run into when using it.

Overall, I like it though. As much as it seems like a deviation from Django patterns, I actually found it easier to integrate Wagtail into existing Django projects than others like django-cms. I find that I typically end up with a "CMS" part of the app that exists fairly independently from the rest. Making foreign-key references to models outside Wagtail isn't too hard, and it integrates fine with the main site templates. Otherwise, I find that I don't often need to do much interaction between the Wagtail parts and other parts (which would be hard). I haven't really done a lot of complicated things with Wagtail though.


Wagtail has a good tutorial to get you started (http://docs.wagtail.io/en/latest/getting_started/tutorial.ht...) and has good enough documentation (that I think would need some improvements). I know it seems a bit overwhelming to start a new project but you can try to learn from existing ones that are available for example the good-old wagtaildemo: https://github.com/wagtail/wagtaildemo, the better-wagtail-demo: https://github.com/wagtail/bakerydemo and of course the RCA (https://www.rca.ac.uk) website https://github.com/torchbox/verdant-rca/ (be careful this is a huge project that uses a little old version of wagtail - 1.6 but most base things are the same in later versions)

Now, for answering your questions I think that Stackoverflow should be fine for asking, most (if not all) questions are answered there (I know that most wagtail developers monitor SO for new questions and answer them promptly). Don't be discouraged by the small volume of questions -- the only problem with SO is that some questions (the more open ones, for example those discussing architecture) are not considered proper for this site and are closed so you should use the mailing list for that.

For the StreamField I totally agree that it rocks however keep in mind that you'll still need to add a model-per-content-type (maybe not so many content types but you will definitely need more than one content type) - I think that the StreamField offers more freedom to the hands of the content editors, using it they can mix and match their content to the page and not follow specific patterns that the developers have decided.

Finally, concerning the deviation from views, don't be alarmed. Wagtail uses a concept called Page (probably should've been called PageType or WagtailContentType but anyway) which is a mixture between a Model and a class based view. So you create your own subclass of pages which are Articles, NewsItems, Events etc. The important thing is that most functionality of CBVs is inherited when serving each Page type so you can override the various class methods like get_context (to add specific things to the context of a page), get_template (to change the template of a page type), serve (to have full control on serving the page) etc. Also you can add mixins similar to CBVs so that many of your Pages will share some functionality.

I recommend you try wagtail and I think that you'll like it!


Great list! Thanks for sharing.

I'd like to recommend django-fsm[1], an essential package for anyone writing workflow-driven applications (pretty common w/ Django).

1. https://github.com/kmmbvnr/django-fsm


Hello thank you very much. I am aware of django-fsm (and it's sister project django-viewflow) but I haven't used it in my projects that's why I didn't include it in the list - all the other packages have been used and tested extensively in various projects so I can vote for them.

Some projects that I had implemented and used workflows were implemented with custom flows (by hand) using django-rules-light to keep a lid on who can do what on each state.

django-fsm is definitely one of the packages I am going to use in future projects that require extensive workflows.


Great list, and thanks for giving Wagtail a shout-out! Your work on it back in its early days is still very much appreciated.

Thank you very much! Both contributing and working (using it as a CMS in various projects) with Wagtail were an absolute joy!

Since this Django post made it to the front page, if anyone with expertise with Wagtail is looking for contract work, reach out to my email in my profile! In particular, we're looking to implement StreamField in our CMS, plus exposing some "templating" functionality to end users.

I love this list, and I'm definitely tacking it on my hobby postboard at home. (Especially for django-reversion which is something I've always wanted and never knew existed!)

I would also like to thank OP for being really responsive to comments. I've been feeling around your blog seeing all this other great content, and I really appreciate the attention you give to people who comment and share :)


Thank you very much for your kind words!

Number one missing package so far is django-haystack. With how important search is, having an easy django-like plugable search engine ready to go quickly is a god send.

Add in the fact that it abstracts over different engines, means you can develop locally with Whoosh (all pure python and virtualenv friendly) and deploy to ElasticSearch without changing your code.


Hello, I am aware of django-haystack but haven't used it in any of my projects so I couldn't include it in my list.

Notice that the projects I worked on and needed full text searching were implemented with Wagtail (CMS) which uses elasticsearch directly.


Great list! I noticed Tastypie wasn't included. I've really liked it, but are there reasons I shouldn't be using it?

In general Django REST Framework is a better package. Hooking in your own customization is less ad-hoc with DRF than with Tastypie, I've found. The DRF documentation is also absolutely stellar and the wider ecosystem around it is really good.

edit: And to my sibling commenter's point, DRF has a funding model, so it's being actively worked on full time.


Having used both, DRF is a lot more similar to standard Django. The views are similar, and the serializers work very similarly to forms so it feels a lot more consistent to use. I seem to remember a post a could of years back where they said they weren't going to be doing more active development in Tastypie, or something to that effect.

Having years of experience with both, I could write an article on why to prefer DRF over Tastypie for general purposes - but one simple reason is that Tastypie is effectively on life-support (taking substantial time to even release versions compatible with new Django versions), while DRF has substantial and accelerating momentum in both its codebase and community around it.

Django Rest Framework is one of the reasons i use django so much. It is done in a really solid way, allowing great power and flexibility over how you want to abstract your rest API. I've used tastypie before, but got the feeling it wasn't as fleshed out as DRF. I remember coming across strange behaviour with complex nested data. Moving over to DRF empowered me.

It looks like the author prefers Django REST Framework (DRF) instead of Tastypie. I can't compare them on their technical merits as I've never used Tastypie, but I do know that DRF is actively developed and has some kind of backing. DRF is one of my "always on" Django packages.

Actually, I remember some years back that when I needed a REST API for a project I started with django-tastypie because back then (circa 2012) was more popular than DRF. Unfortunately, I did not have a good experience with it (too long to release a new version to support new django version) so I switched over to DRF and hasn't look back since.

I'm not really familiar with the status of django-tastypie right now but from what I see from the other comments it probably is better than tastypie.

Also please notice that I wanted to include one of each kind of package in the list since it's the actual list of packages I'm going to use when I need a feature - so there's no reason to include both DRF and tastypie (yes, django-simple-history and django-reversion were both included but as I explain in the article they have different usage models).


Great list. I use a few of these on all projects.

Interestingly, django-webpack-loader has completely replaced django-compressor and all the other static bundlers. I like how configurable webpack is and how much control it gives you.

Anyone else completely switched over? Every single static file runs through webpack for me now, and I couldn't imagine ever going back.


Hello, I am aware of webpack but I haven't jumped in the webpack wagon - the tool I use from the node-js world for asset management is browserify which is much simpler (I've written a couple of articles about it: https://spapas.github.io/2015/05/27/using-browserify-watchif... and https://spapas.github.io/2015/11/16/using-browserify-es6/).

However, as I mention in the post, I don't using node-js tools if you don't need em. If you have a couple of css / js files that don't do anything fancy (i.e no es6, no require etc) then I don't thenk that there's any need to add a huge dependency (node-js and friends) to your project. django-compressor (or django-pipeline https://github.com/jazzband/django-pipeline which is also good) should be more than enough for your needs. Also, notice that webpack / browserify don't understand javascript or css snipped that are inlined in your django templates (django-compressor understands them all right).


Could someone please concisely describe if there is a use-case where Django offers utility above what Flask can provide?

If you're building a complicated, full, user-facing application, and start with Flask, you'll find yourself reinventing most of Django.

Eg, a user model with pluggable authentication and flexible permissions model, ORM with migrations and associated automatic form generation and validation, static asset compression pipeline, CSRF and CORS protection, etc.

Yes, you can find Flask libraries to handle pretty much all of that stuff, but it's on you to pull it all in, glue it together, figure out which ones work well together, and document it for any one else who might work on your project. Especially for some of the security related things, it's definitely nice to know that those parts have been integrated and tested and audited already.

It's a tradeoff. With flask, you can get exactly the components you like; with Django, they're mostly chosen for you. If you don't like Django's ORM, you can replace it, but then you lose a lot of the advantages that come from its integration with everything else.


To extend this a bit, I would consider Flask if I didn't have a relational database. Without a relational DB, you lose the ORM and most of the ecosystem that's tied to it. At that point, something lightweight and simple is appealing.

In practice though, when I've been in that situation, I've found it more compelling to just drop Python and use Go instead. I guess with a use case that relied on NumPy, Pandas, Tensorflow or something Python-specific but that didn't have a UI, I might still go with Flask.


>To extend this a bit, I would consider Flask if I didn't have a relational database.

Use the Flask-SQLAlchemy plugin. It works beautifully. SQLAlchemy is a very good ORM.


Did you read my original comment? My point was that if you're using Flask, you are responsible for pulling in all of those components and making sure they work together, not that there weren't good components available for Flask. I'd rather use Django if I need all of those things and want them to work together. If you don't have a relational database, Django's ecosystem advantage (much of which hinges on the ORM) isn't as strong and Flask becomes worth looking at again.

The "Flask-sqlalchemy" plugin, as its name implies, makes Flask and SQLAlchemy work together just fine.

Ecosystem aside, who do you think has better ORM concepts: Django or SQLAlchemy?

I haven't really used SQLAlchemy in anger since about 2009. I remember it being fine but I can't really say much else about it. That said, I haven't run into any limitations of the Django ORM that have driven me to look at other ones.

Exactly this. Every production Flask project I've seen has a massive requirements file to bolt on functionality that comes built into Django. The second I realize that I need an auth system or may potentially have a DB migration, I select Django.

Frankly, I don't see the attraction to _bring your own_ frameworks in most cases (though I've done it for very specialized cases). I get paid to get projects done, not to reinvent the wheel.


Built in everything. Users, auth, admin, ORM.

Flask is the opposite: Bring Your Own Everything. It's not hard to replicate the functionality of Django but there is surely utility in having everything boxed up and ready to go.


Never use the built in user. Always start a project with a custom user extending abstract user.

At some point you'll want to customize the user in some way (like making the username case insensitive), and you don't want to be dealing with migration dependency conflicts when you do.

For some reason the Django team is really against any attempt to fix that. They're almost hostile in their discussion of it.


OK. Well, I've been building Django apps since around 2007/2008. More than 50 deployed to production, many still running/maintained. Never once had a problem using the built-in user model. Do you work in some vertical that makes this a particularly common problem for you?

I don't think the parent comment is saying don't use the built-in user model. The comment is suggesting to sub-class/extend the built-in user model. So you can use much of the built-in functionality and add/change what you'd like, eg. to add a birthday field

There are obviously other ways to do this, perhaps by creating a Profile model that relates to a User.


Yes. Technically you should extend the abstract user model or things get real broken real fast, but that still gives you all the functionality of the built-in user model right out the gate.

The main reason is that if you ever want to change how the username works, it will be a major pain to do if you've been using the built-in user model and already run migrations.


You've never had to extend the user model? I suppose you could just do most extension with a model that has a 1-to-1 with users and use a proxy of the built-in model for the rest, but it seems much simpler to just start out with a user model you can customize easily.

I create Profile's that are mapped 1-to-1 to django.contrib.auth.models.User all the time to hold additional fields. I consider that the "orthodox" approach that Django encourages.

I've even implemented "case-insensitive username" a time or two, but done it by overriding some logic in the login view rather than modifying the user model.


That seems like a lot of trouble when you can just start out a project with a few lines of code extending abstract user. The case-insensitive username can then just be done by making the username a case-insensitive text field (admittedly only available in Postgres, but that's true for a lot of awesome Django features).

I don't mean to be mean, but your answer reminded me a lot of the last row of this comic: http://www.giantitp.com/comics/oots0050.html


But you see, I find that overriding the one little bit of view code (literally a couple lines of code) to change the one thing I want changed is by far the simpler approach rather than changing the whole structure of the user model and introducing who knows what kinds of subtle bugs elsewhere. When the requirement for "case-insensitive username" comes in, it's always turned out that all they really mean is "If someone types 'Bob' in the username field rather than 'bob', it should still work". And again, even that has been such a rare thing that I've probably spent more time writing this comment here than implementing it in code, so why overcomplicate it?

If you change login and forget to change registration, suddenly "Bob" can't login because "bob" just signed up for the service and your login is now returning 2 users. Django puts username validation on the model field for a reason. It's better to have it all centralized.

The nice part about extending the abstract user from the start is that you can still just use it exactly like you'd use the built in user. There's no difference. It just gives you more options in the future.

It literally only takes 8 lines of code, including imports and a "pass" to do.


Heh, wish I'd done this back in 2012 with my app. Admittedly it wasn't as easy to do back then IIRC.

Now one of my to-do-one-day jobs is rolling my UserProfile model back into a custom User subclass... would save a lot of DB queries. :)


Yes. The joy of reasonable defaults and an opinionated way of working.

Some people loathe that but it frees me to think about the customer's actual problem rather than merely tidying my pencil case.


Oh, I get it now. Thanks!

Some reasons you might pick Django over Flask:

You want to be productive out of the gate - Django has the batteries included philosophy, so there's less time spent wiring together different libraries.

Fewer architectural decisions - Django is fairly opinionated about where to put things (less than Rails, but more than Flask). For some people who have problems with bikeshedding, this is a big win. Having all of the pieces tightly integrated means less time fiddling. As a sidenote this can really help when onboarding new developers. A complaint I've heard with Node/ReactJS apps is that they can be organized in any number of ways, and so knowledge doesn't carry over from one project to the next as well.

Class based views - Django has a really cool concept called class based views, where you can compose the "controller" functionality of your app with mixins. See ccbv.co.uk for a nice explanataion. Django is really really good at CRUD apps, and you are probably building something that does mostly CRUD or can be convinced that it is CRUD.

"More popular," and therefore more people use it and therefore more open source 3rd party packages to use and more people to get help from and more people to choose from when hiring. One metric - Stack Overflow has 154k questions on Django, and 18k questions on Flask.

"More mature" - this could be questionable, but Django is 12 years old vs Flask's 7 years, and Django has 25k Git commits vs Flask's 3k. This means more person-hours have gone into Django than Flask.

None of this is to say that Flask is not a capable framework. It looks pretty solid for what it offers. But the choice of framework is a decision that should be informed by the business requirements, unless it is a personal project and then use whatever you want. Hope this is helpful.


If you're interested in trying a hybrid approach, I find that Web2py offers the best of both worlds. It's batteries included in that it offers most of Django's features, but the author understands API aesthetics, much like Flask's author, and so it's a delight to use.

I started with Flask, tried Django, was disgusted by the gross API, and then I found web2py where I now sit happily :)


I love Flask for mini-apps and micro-services. I pretty much use it when I want to run a single python file with a web-facing component. It's also great when I need to build simple celery or task/cron-based apps. Like the other commenters have already pointed out, if you need a full-fledged website, Django.

The killer feature is the ecosystem. You have plug and play libs for every thing.

I too am curious. I had trouble getting started with Django but once I tired Flask everything seemed to make sense.

A definite downside of Django is learning curve. I'd argue Django is harder at first but easier in the long term.

Exactly; it takes time to learn the thing—it's huge compared to Flask. The documentation is killer though. I've been learning django for at least a few years now. I try not to rush, I know I'll figure it out eventually is basically my philosophy.

Django definitely has top tier documentation. I'd recommend first reading the official tutorial, then trying to make something with it and referring to the different sections as needed. For people wanting to go to the next level Two Scoops of Django is a fantastic book on best practices, and even more opinionated than Django, which I consider to be a great thing.

Your site is full of juicy content, thanks!

This list is impressive, but a lot of these packages are used to generate HTML which is then not usable for SPA.

Do any of you have a similar list for SPA oriented projects ?


The 2 that come to mind are DRF and django-webpack-loader. The webpack loader is great if you use webpack, and want to use the Django template language to render your index.html. Sometimes server side rendering of initial data is nicer than having to send all initial data down w/ AJAX calls.

honestly? use nodejs for that.

django can still give you the backend through DRF or django-graphene, but frontend for SPA is (in my opinion as a dabbler that hates js) way better with node.

take markojs as an example. creating an app with marko-cli gets you a simple demo application with 3 webpages and you're ready to go. you can use concise html syntax (way cleaner and i'm still astonished that there is no similie for django). the stateful components syntax is way cleaner. this is especially true for for/if/whatever tags

like it or not js is the language of the web.

django is still wonderful if you're not focused on SPA applications though. And this includes websites with contents which update through ajax calls.


I believe it works like this:

1. Django for the backend. Nothing but an API (DRF, GraphQL, some custom views or whatever one fancies) and - if server-side rendering is not necessary - a catch-all view that spits out HTML file with the JS bundle. It either doesn't know anything about the frontend, or, possibly, can read Webpack stats file (using django-webpack-loader) to figure out correct bundle filename.

It may also run Django Admin Interface, independently from the SPA - as an almost independent "back office" site.

2. JS/TS/Elm/whatever and, probably, Webpack for the frontend/SPA itself. If server-side rendering is desirable, a Node-based server. All it knows about the backend is the API contract. Trying to somehow embed JS into Python/Django is not easy, error-prone, and I just don't see any benefits of doing so.

3. A router that sends requests to the correct piece. I've always used a simplest-possible nginx setup with location /api/ { ... } and location / { ... }.


It was a few years ago that I used it but I found django-autocomplete-light pretty unfriendly and not very light. It was far easier to roll my own.

Hello, I agree that previous versions of django-autocomplete-light were cumbersome to use. However, since version 3 most of the magic has gone away:

1. Add a class-based-view that returns the search data (inheriting from autocomplete.Select2QuerySetView)

2. Register that view with your urls.py as normally (but be sure to give it a name)

3. Add a form field by specifying its widget using the autocomplete.ModelSelect2 widgt, passing it a url='view-name' parameter (which is the view name you used in 2).

4. Don't forget to include jquery and {{ form.media }} in the views that uses your autocomplete.

5. Done!

Seems pretty easy and friendly to me!


Great resource! Perhaps make it easier to find on your site by adding it to your "Django" category?

Thank you! Yes, I agree that the article fits better to the django category than the python one so I moved it, thanks for the heads-up!

Very nice list. Bookmarking this!

One nitpick on your blog layout. I was clicking the h3 for each library, and thought the links were broken. :)


Hello, thank you very much!

Now that you mention it, I also find this behavior (clicking the header returns you to the TOC) and since it can be easily fixed (change .. contents:: to .. contents:: :backlinks: none) it should have been fixed by now :)


Great reference. Thank you, spapas82. Bookmarked!



Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: