My essential django package list
spapas.github.io
spapas.github.io
This also leafs me to favour more stay-out-of-my-way add one like django-silk over django-debug-toolbar
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!
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.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.
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.
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.
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!
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!
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-...
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!
I'd like to recommend django-fsm[1], an essential package for anyone writing workflow-driven applications (pretty common w/ Django).
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.
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.
Notice that the projects I worked on and needed full text searching were implemented with Wagtail (CMS) which uses elasticsearch directly.
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.
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).
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 :)
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).
edit: And to my sibling commenter's point, DRF has a funding model, so it's being actively worked on full time.
One nitpick on your blog layout. I was clicking the h3 for each library, and thought the links were broken. :)
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 :)
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.
Some people loathe that but it frees me to think about the customer's actual problem rather than merely tidying my pencil case.
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.
There are obviously other ways to do this, perhaps by creating a Profile model that relates to a User.
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.
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.
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
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.
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. :)
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.
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.
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.
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.
Use the Flask-SQLAlchemy plugin. It works beautifully. SQLAlchemy is a very good ORM.
I started with Flask, tried Django, was disgusted by the gross API, and then I found web2py where I now sit happily :)
Do any of you have a similar list for SPA oriented projects ?
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.
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 / { ... }.
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!