Congratulations to the Django project and contributors on a big LTS release. And a huge thank you for the consistently excellent framework that so many have built their web dev careers on.
I'll post this as a Show HN soon, but I'll mention it now as a soft-launch introduction. After a decade of using Django I started a project I always wanted to exist: backported security and bug fixes to old versions that the Django project has dropped support for.
I've seen many Django projects eventually get stuck on an old version as the team I'm on is forced to defer upgrades in favor of commercial pressures and essential product delivery.
So you can subscribe to https://www.codestasis.com/ to stay patched on your old version, removing the urgency to upgrade. Then unsubscribe when you're caught up.
It's free for personal use and a paid subscription for businesses and organizations.
It's a project/business that I've suggested a few times on the mailing lists and I'm truly surprised it's taken this long for someone to start one up. I'll be interested to see how/if the price points change over time.
The pro tier is approximately equivalent to <= 5 hours of developer time per month. At a minimum it gives useful information to developers trying to communicate the cost of delay to management. I think my org may have opted just to pay at one stage, considering the migration from 1.8 to 1.11 was measured in weeks not days.
Thanks! I toyed with the idea since 2014, after I was stuck managing a Django codebase with a gnarly middleware for a multi-tenanted website that precluded an easy upgrade.
I bookmarked this thread in 2019 where tptacek provided the impetus for the project with a one-liner suggestion https://news.ycombinator.com/item?id=20378409 And I've just noticed you replied then too!
I also assumed someone would get around to it. It took a while to get to a place I could start and then way longer to develop than I assumed. (Not just the backports but the tooling, testing infra, and website)
That's good to hear on pricing since it reflects my experience and is my thinking behind the initial price points.
This is a great idea...unfortunately a company that skips on Django security patches and bug fixes will very likely be doing the same for everything else (frontend libraries, servers, etc). But there's not much you can do when you're stuck on a feature-factory treadmill, and this looks like a cost-effective way to ameliorate the problem.
Awesome project! Bookmarking for sure. Dumb question: after signing up, am I getting some access to a privately hosted repository(pypi.codestasis.com)? How is the mapping between personal/pro plans and features done? Are different plan levels using different repository?
Btw, might have overlooked, if I'm purchasing for my org, I would like to look at the commercial license. Can you point me to it? Or put it online if not currently available? I'm not using your service at this moment, so feel free to ignore the request as well.
I think it's a bad idea and would recommend grandparent to charge everyone for the service, then donate parts of the proceedings back to the Django project.
Great project. Looks like running outdated Django will be cheaper than running outdated rails... Although I can't remember if there were multiple players delivering "lts" versions for ruby/Rails?
Django is the gold standard for consistently pushing out reliable, well documented open source software without any marketing fluff or other bs. The amount of value the team is adding to the world can't be overstated.
A couple of years ago(2014) I made my first Python website and really enjoyed, however when it was time to put it onlin I quickly discovered that setting up hosting and configuring it was as large a task in getting to know pip, env, unicorn, apache2 and a plethora of other software to host it, is this still the case? Becaue this is what keeps me of hosting websites with python.
I had similar issues with Django where I felt that running on localhost was fine, but getting it production ready was a headache.
Huge shoutout to dokku[1] which I used on my latest deployment and it makes it super easy. Lets encrypt support was the easiest I've seen and you redeploy with git push.
This was a huge pain for me in the past to the point that I started maintaining a boilerplate to avoid it [0]. But I've heard so many good things about dokku that I think I'll give them a try soon.
How does dokku work with regards to mixed multi-hosting (Apache virtual hosting) on a server?
For example, you have five sites, three are PHP and two are Django. Can it deal with that?
Also a neat "for free" feature of CPanel hosting is that you get super easy email hosting. This can save a lot of money for small and medium businesses. While some would be interested in using Django on these systems, it is in a range between painful and impossible.
This means that you have to now switch to a single-app/domain-per-server scenario (like, Heroku) which is expensive. And then spend more money to host your email elsewhere.
Frankly, this has been one of the largest sources of friction for me with Django. I love the framework and would like to use it exclusively but the transition from local development to deployment can be daunting.
Dokku will allow you to host multiple applications on subdomains for which you can create CNAMEs in your DNS settings. Dokku is more of a mini self hosted Heroku without a dashboard so you'll lose out on cpanel features like email hosting.
But If you're not uncomfortable using docker, you can check out Cloudron [0] which handles email [1] and gives you access to quite a few web apps you can easily install on your server. It supports PHP app deployments [2] out of the box but for Django, you'll have to dig a bit deeper into their docs to learn how to deploy a custom docker based app [3].
BTW, it's not that I am not confortable with Docker. In fact, we use it for development. This is more about time and resources. I run more than one business and a couple of them have more than one domain. We pay for a decent VPS and can host and manage as many email addresses and applications as we want. Yet we have to limit it to PHP (either pure PHP or something like Wordpress). And, BTW, I hate using PHP.
For internal stuff we use Django for everything. Host it locally, etc. We even use Django as the front end for industrial automation applications (which imposes interesting challenges, like maintaining state in the database as well as reliable activity logs and more).
If I were to summarize the difference between doing Django for the web vs. PHP for a business it would go something like this:
PHP: Get almost any server. Setup the domain, emails, setup database, upload code. You are up.
For Django you could do this (some of this is dated, just making a point):
In other words, you are way past the beauty and simplicity you got during local development.
And, of course, for most, if not all, of the above, you still have to deal with setting-up business email. Which means you either get the same VPS you got for the PHP case and point the MX record that way or, spend a bunch of money per email address with something like Gmail. Etc.
Django is fantastic. Somehow, someone needs to figure out how to be able to launch the same type of site you might develop locally to a standard VPS just as easily as what is possible on your local development system. Yes, of course, for more advanced sites you are into separate DB, static, application, etc. servers. That's a different use case. I think what people are saying is that there's a great divide between "runserver" and actually being on a server from there without paying more for specialized deployment services.
Another way to look at this that Wordpress will never be challenged at scale if a better tool like Django isn't easily accessible to developers who are not Linux/server experts. I was running Unix before Linux came out and have used Linux in various forms (including early embedded systems applications) since the beginning. If someone like me recoils at the idea of actually deploying Django in the real world I can't imagine what this might feel like to others who might lack the experience.
In other words, I can do the work. I just think it's unnecessarily complex and not enough effort has been expended duplicating the ease of local development for basic to mid-range Django apps at the production server level.
That's true. Every time I have to launch a new Django site I always have to spend an hour or two reading docs to refresh my memory on how to configure everything. SSL, systemd services, certificates, uwsgi, database setup, permissions, dns, email, etc. Someone could probably make a lot of money by creating some kind of Django+uwsgi+docker+nginx+postgreSQL bundle to make this process as painless as possible.
Here's one way I look at it. I don't need or want the simplified local development environment. As neat as "runserver" might be, it actually creates a problem, because going from there to production feels like the difference between driving on a lazy country road on a beautiful summer day to driving in the middle of one of the most chaotic cities in the world in a storm.
My humble suggestion would be that this form of easy local development should be deprecated in favor of creating a server-based local development model that translates 100%, without friction, to production servers.
Simple example, I do all my web development work either using a Linux server VM on my Windows machine or a Linux server on our network. These days, running a VM with whatever flavor of Linux isn't a problem for anyone. Django could, out of the box, come with such an arrangement for local development. Perhaps in the form of an Ansible script.
I would want to see at least two development scenarios supported. The first would be as close to bare metal as one might want to get (say, Linode) and the other should be setup to work on something like a GoDaddy multi-hosting VPS.
This would allow for frictionless transition from local development to production deployment for a huge class of sites. Anyone doing anything more complex than that would have the time and maybe even the engineers to devote to designing and deploying a complex infrastructure with multiple kinds of servers, load balancing, etc.
Bottom line is, I think "runserver" is a neat trick but it likely ends up causing far more frustration than might be obvious. I have spoken to a number of people who tried Django, liked it, and moved on in frustration when they hit a brick wall when they had to figure out deployment.
I like to say that people don't go to the hardware store to buy a drill bit. What they are after is a hole. It's the same with websites. Nobody needs a Django website. Nobody. There are a bunch of alternative technologies out there. Which means that if Django makes "getting a hole" difficult, people will just move on. They don't want to become experts in manufacturing drill bits, they just want a hole.
I am definitely not a dokku expert (for that I would recommend reaching out to their Slack channel[1] - a lot of great support for an open source project).
But in an attempt to answer your questions:
- Yes, you can host multiple sites on one server in dokku.
- That's a good point, I'm sure a lot of people like that about CPanel hosting. Maybe something like this poste.io implementation[2] would be what you are looking for?
- Dokku has the benefits of heroku but without the vendor lock in/pricing. Pick your preferred VPS host that runs for a few dollars a month and you are set.
I was in a similar position a few years ago too, until I forced myself to learn Docker.
Now, all my projects are started from the same building blocks: Docker + Django + Gunicorn + Nginx + Postgres. And I love it.
Now I have traefic at the top of My to-learn list so that I can host multiple projects in the same VPS.
Last weekend I learned to use 11ty — the first static site generator I managed to grasp — and I'll entend to use that for projects that don't need this level of "complexity".
> Now I have traefic at the top of My to-learn list so that I can host multiple projects in the same VPS.
Why do you need that? Nginx dispatches based on the domain name so you can easily host multiple Django sites on the same vps. I use the same tech stack as you except with uwsgi instead of Gunicorn.
At least with pip and env, you'd have a hard time doing general tasks in python without getting to know them anyway.
You can also shortcut a lot of that with a hosting service like Heroku, which takes on a lot of the mental overhead for you.
You've made me curious to ask, what programming environments don't have a significant learning curve when you get to the hosting portion, short of a "no-code" hosting solution?
PHP. Deploying small-to-medium PHP projects to production has historically been "move these files to your web root, initialize/seed your database if you have one, and that's it." It's really easy to underestimate how valuable that is in certain contexts, and how much that's contributed to PHP virtually owning the low end of the market.
My assumption was always that other languages would find a way to get closer to that model -- never quite to that level for various technical considerations, but close. I'm not sure any really have, save, as you noted, through dedicated hosting services. Fortunately, though, modern PHP frameworks have come to the rescue by becoming far more difficult and fiddly, to the point where both Symfony and Laravel's online tutorials begin with installing Docker.
> You've made me curious to ask, what programming environments don't have a significant learning curve when you get to the hosting portion, short of a "no-code" hosting solution?
With java you can deploy a "fat jar" - a single executable that contains everything it needs, including the web server. You start the jar, it binds to a port, and you're done.
I recognize this from some years ago, but it's not an issue any longer, as long as you go to a modern host (ie. Heroku). The old "optimized for PHP"-hosts still make things hard of course...
Having set up some php servers myself: it's not a lot harder to host a python app. It is mostly the that hosters have optimized for php but you could do the same for python
You'll still have to configure gunicorn or another production-ready (w|a)sgi server to serve the app out of the container, but it's much easier to manage dependencies for django in a containerized environment. It's even easier if you use a deterministic package manager like pipenv or poetry instead of old requirements.txt files
Hey, could you please stop posting in the flamewar style to HN and in particular please omit swipes from your comments here? Those things break the rules and destroy the curious conversation that the site is supposed to exist for.
This usage of "a couple" is so common that it's far beyond some weird thing some people say, and telling a non-native speaker it's wrong is not doing them any favor - it's basically universally accepted usage. FWIW, if you have a reference to a styleguide that explicitly addresses it I'd be interested - I did a short search and didn't find anything, but I also don't have easy access to the full text of some major ones. But even then, disagreeing with some style guide doesn't make anyone "illiterate", or "needing english lessons" (which by the way explicitly teach people that meaning of couple, because you need it to understand English in practice).
(and I didn't flag your original post, because I don't think merely being wrong justifies flagging)
A couple thoughts on django as a long time user. First, the good:
- Django was the first framework i learned when learning to code. It's documentation was amazing, and it made conceptualizing an MVC framework really easy.
- Django's ORM is phenomenal for managing migrations of a relational database, especially postgres with stuff like jsonb. I've even included it in non-python projects, just to handle table migrations/rollbacks.
- The huge ecosystem is amazing. Great for rapid prototyping. Plugins for all kinds of crazy stuff.
Now the bad:
- In some ways it feels like a relic of an earlier stage of python. It's support of asyncio is spotty at best (running the orm in a thread executor not a good work around).
- It's support for type enforcement with mypy is not great. This is maybe my biggest issue with using it on large collaborative projects.
- It doesn't play nicely with a lot of the rest of the python ecosystem. Want to swap in SQLAlchemy? Sorry, no dice. Want to have nice swagger documentation? Use django rest framework or you're out of luck (i know it can be done, but it's kind of messy). So in short, it's a bit of a monolith.
These days I tend to only use django for it's orm in situations where i want a quick ad hoc database for something, or for rapid prototyping. If I'm going to do a larger project in python, I'd definitely go with FastAPI. But still, gotta appreciate that it's there, and has been reliable/well maintained for more than a decade.
>- It doesn't play nicely with a lot of the rest of the python ecosystem. Want to swap in SQLAlchemy? Sorry, no dice.
Being extremely opinionated about stuff like ORM and admin is partly how it developed such a rich ecosystem of plugins. Those plugins exist because they can build upon those foundations.
Flask, by dint of being unopinionated doesn't have solid foundations that its plugins can build upon. This is why you get stuff like quokka (a flask cms plugin built on mongo) while other stuff assumes sqlalchemy and other plugins built plugins for various different storage backends.
I think you could probably abstract away some of the differences between djangoORM and SQLalchemy. Maybe something like a model class that uses sqlchemy for the underlying orm interactions. Not that i really blame them for using their limited dev resources elsewhere.
Django is really great for writing Django apps. It's not great for writing other kinds of apps.
If your app is a CRUD interface over a relational DB, it's awesome and I mean that sincerely. I'll happily reach for it instead of reinventing that nicely crafted wheel.
If your app isn't -- say, it's backed with noSQL or maybe is a frontend over a bunch of backend API calls such that you're not using its ORM or its permission model -- then it feels like a box of pain.
How productive are you with FastAPI compared to Django? I’m thinking of things like forms, error handling and all the other extra stuff that comes with decoupling the frontend and backend.
The main thing I would wonder about is if there's a good auth plugin for FastAPI.
I am not a huge fan of Django, but if you have already chosen Python, it is really hard to argue with having good, battle-tested auth system out of the box.
The other side of the coin is that django's auth system is pretty rigid. Adding additional fields to the user object is clunky, and trying to do an unusual auth flow can be downright ugly. Dealing with that a few times can leave you a lot more open to designing your own and/or patching together other libraries. At least, that's how it went for me a few years ago.
Not nearly as productive. That's why django is definitely a better choice for rapid prototyping. But if I'm working on a larger project that I'm hoping to maintain for years, up-front productivity usually takes a back seat to maintainability/scalability/extensibility. For those, I'd go with FastApi
If anyone is curious I just updated my Docker / Django starter project to use 3.2. It uses Docker Compose + Django + Celery + PostgreSQL + Redis + Webpack + TailwindCSS and it's available at: https://github.com/nickjj/docker-django-example
As an aside it's also using TailwindCSS 2.1 with the JIT compiler enabled.
> What's your take on Tailwind so far? I've found the lack of a react offering has really slowed me down.
It's working out well for the most part, but I don't use React.
I mainly develop server rendered apps and sprinkle in JS as needed.
The only weak link with Tailwind IMO is the lack of JS for doing common things like hiding / showing menus, tooltips, modals, tabs and other stuff you'd find baked into Bootstrap. I know there's some JS included in the TailwindUI components but it's not for JS libraries that I use. I prefer using StimulusJS which isn't something they support at the moment.
Fortunately there's a bunch of StimulusJS Tailwind examples provided by the community so it's not too bad in the end.
I imagine it's hard for Adam because there's React, Vue, Alpine and StimulusJS, all of which are popular enough where there's a good amount of users using them. I'm optimistic that he'll think of a way to cater to all of these users in some way, it'll only be a matter of time. NOTE: This is just speculation, I'm not affiliated with Tailwind in any way.
The creators of TailwindCSS also have a paid offering called TailwindUI (just pre-created components with documentation for your application and marketing site) that has React support. It also comes with Figma mockups for each component. It's a bit pricy but very high quality.
I went back to this thread to find the docker-django-example. I have to say, this is really solid work, and thank you for sharing it. Tailwind is commercial I see, is there a free way to get set up with a nice looking "dashboard + sidebar" UI without buying the Tailwind UI?
TailwindUI is an optional paid product that has a bunch of pre-made TailwindCSS components created by the makers of TailwindCSS. Basically pre-made widgets and layouts.
Just upgraded my side project to both Django 3.2 and Tailwind 2.1 (with Jit enabled). No issues at all, other than some deprecation warnings on some 3rd party packages that will probably be fixed soon.
We use TailwindUI - combined with Django gives a really nice kickstart on new projects. Just made a Proof of Concept last two weeks for an internal business app for a new customer and did impress them easy with a working app + login + responsive nice looking layout. Used VUEjs for menu's, keyboard events and a location picker.
I've used more component-based frameworks like Bootstrap before, but I've found it's easier to have a set of utilities and build my own components on top of that.
Celery describes itself as a "task queue" but I find it a bit confusing: it's a job manager, which needs a queue from which to pull/push jobs. Redis is this queue
Django is a sensational piece of open source software - I've used it on so many projects.
Seen some replies saying it's a pain to deploy - look at guides for Heroku and Google's App Engine - both are super simple processes. If you want more control AWS Lightsail also has a great guide.
I have been using version 3.2 since Beta. Deployed on a production application, so far without a single problem.
I highly praise Automatic AppConfig discovery and BigAutoField for pkey.
I highly recommend the transition to Django 3.2
The ability to customize the type of auto-created primary keys is also one step towards fixing one of the long-standing issues in Django: https://code.djangoproject.com/ticket/56
I would grab the "Django Crash Course" from Feldroy[0]. It is a tutorial starting from nothing, and you build a very basic app. Which sounds unimpressive, but it shows you all the best practices for app layout etc and when combined with Two Scoops, provides a great foundation.
After that, to really get to know Django, you'll want to do some "unconventional" things like use a class based view for a page with 3 forms... That should give you the "ah ha" moment.
The official Django tutorial is pretty good. Two Scoops is good for going from beginner / intermediate to intermediate / advanced knowledge, with best practices in mind.
My website was built in the 1.x version days and I don't think there have been any material breaking changes. My website is moderate in complexity... authentication, database, forms, file uploads, email, language support.
I remember Zope was pretty universally disliked by Python programmers. But it was for a time probably the most enterprisey thing with Python inside, so maybe it got more points in corporate places as something to try as an alternative to Enterprise Java Buzzwords.
Before Django there was a lot of choice and active libraries / frameworks for Python web app development, IME most apps gravitated more towards "ala carte" use of libraries than one size fits all frameworks, a bit like people do in Clojure today.
Zope was more like a ready to use CMS that incidentally enabled you to mod it using Python in a clunky way.
The object database part of Zope (ZODB) was pretty cool though, used separately (inside Zope the framework-enforced object schema made it just clunky). As long as you didn't let it spread too wide over your codebase. But it had transactions, flexibility of (and problems of...) schemaless, and replication, a long time before the "NoSQL" craze.
Replying to myself: for those interestedin ZODB, there's also a simpler standalone remake called Durus (by well known Pytoneer Neil Schemenauer): https://github.com/nascheme/durus
It might not have the replication / distributed features though.
I recall there being some 'wilderness years' between people generally deciding that Zope was a bad idea and Django 'winning'. I remember using frameworks like Turbogears and CherryPy for a while before Django and Flask split the 'market' between them.
This is how I was seeing things play out in the early 2000's:
— Python Programmers: why do we still have to be doing this in php/Perl/JSP/ASP when Python exists? — The World: here's Zope — Python Programmers: is that supposed to be joke?
Then in 2003 WSGI showed up and it was a matter of time, leading to the years of wilderness that you describe until Django won out. I confess that I was more team Pylons, but happily conceded.
Ah, Zope, that wonderful monstrosity. I build a purchase order system for my company in it back in the day. It made that type of business app very easy, as long as you didn't expect any kind of performance or scalability. The magic of Zodb was also its weakness. But even today, I think it would still be faster to develop a basic business app in Zope than in Django.
I remember being quite interested in zodb for app development in python since it alleviates the need for an orm... it is a bit like a document store, right?
Django is so refreshing when you come from JS world. Combined with Python is such a pleasure to do stuff with it.
My favourite model is Django backend and React frontend though (I try to keep it as lean as possible).
Congrats!
Looking forward to update my projects.
Django rocks. I have been using it in every side project of mine since 2016. Love it, recommend it especially for teams with very less time and more features on backend.
Depends what you want to do, and why you're doing it. Very often when I make something in Flask, I end up with so many dependencies it might as well be Django (but without the cohesion). On the other hand, Django might be overkill in some situations (e.g. a small API without a relational database backend).
I was forced to fall on this trap once: a guy has a small Flask app up and running, and he asked for help to implement: an ORM with migrations, an Admin and form validation (among other things that had nothing to do with Django such file parsing).
I suggested to migrate the app from Flask to Django while it was small and simple, but he refused for Django is "too big and complicated". OK, then. We ended up creating a monstrosity of Flask half-assed packages to include functionality that is already included in Django (think cache, csrf, admin...), plus WTForms, plus SQLAlchemy, plus Alembic, hard to test, hard to keep updated, hard to deploy, and so complex that it turned non-migrable to Django. Development felt like walking through mud.
I love the paraphrased quote. It’s a bit ironic in that Python programmers love the batteries included standard library but quickly jettison that idea when it comes to Django vs Flask.
Flask’s marketing of a simple route decorator makes it seem light weight but once you add everything else it becomes Django.
but he refused for Django is "too big and complicated". OK, then. We ended up creating a monstrosity of Flask half-assed packages to include functionality that is already included in Django (think cache, csrf, admin...), plus WTForms, plus SQLAlchemy, plus Alembic, hard to test, hard to keep updated, hard to deploy...
Heh. I've done that. Impressive how quickly you can go from "I literally need three or four REST end points to let users query this SQLite database" to, well that.
I think one common misconception is that Django can't be used in place of Flask when you want a minimalist set up. And to be fair, I used to think the same until I read Lightweight Django [0]. Their smallest django project code is just a couple of lines:
import sys
from django.conf import settings
settings.configure(
DEBUG=True,
SECRET_KEY='thisisthesecretkey',
ROOT_URLCONF=__name__,
MIDDLEWARE_CLASSES=(
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
),
)
from django.conf.urls import url
from django.http import HttpResponse
def index(request):
return HttpResponse('Hello World')
urlpatterns = (
url(r'^$', index),
)
if __name__ == "__main__":
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
Granted, it's not as terse as Flask's hello world example but it's still quite short.
I think the comparison is not so much lines of code but conceptual overhead. With Flask you create an app instance and call @app.route() with some Python functions and run the app. Granted it's probably not going to do much, and by the time you build out a real-world application with a SQL database, authentication and so forth you're going to get diminishing returns, but for a beginner who just wants to know "how do I make a web page using Python?" it's great.
How big is the smallest Django project after you add proper authentication (signup, login, pw reset, oauth2, 2FA)? Last I checked it was rather terrible.
Django has a substantial learning curve and you may need to spend more time to get started. But ultimately to do the same thing in Flask you have to spend comparable time to learn, except that Flask lets you start much quicker into your learning. As your Flask project grows you find out it is not actually that easy nor convenient.
This is of course my experience only. I decided to just stick to Django (and DRF) and I feel no need to use anything else.
For performant services I use Go.
I generally agree philosophically but PHP has a couple of features which make problems more likely: the C style error handling increases the odds of problems being ignored (yes, Python can have except:pass but that’s more obvious & requires intent) and the mushy typing hits even experienced developers who didn’t think about whether they needed === instead of ==. The standard library’s inconsistent parameter ordering for related functions probably deserves a mention here, too.
I started using PHP around 1998 and quit cold-turkey about a decade later for Python after noticing across the board quality improvements on every project. PHP isn’t terrible but using it requires constant diligence and few teams had the extra time and skills to use it safely.
Then lets look at those semantics: what is bad, and is anything ever bad? Because I think mostly all frameworks are pretty easy in the small, it's how they help/hinder with larger projects that demonstrates their worth.
On that basis, sure, it's up to the user to figure out what's appropriate; and a shovel is not an appropriate writing implement - you could say it's even a "bad" one.
1. It’s tricky to use in non-web contexts. If you ever need something to happen as a response to an event which is not a web request, Django makes this difficult and ugly.
2. Django also more or less requires ownership of the database in order to function as intended. If you want to have your Django objects in your own database and handle schema changes centrally (to, for example, alleviate problem 1 above), you must also abstain from some of Django’s power, i.e. migrations, etc.
For (1) The simplest is probably just running a Django management command - maybe from a cron job.
But maybe I'm misunderstanding the kind of task you have in mind?
For (2) - you seem to be saying "if you don't want Django to handle migrations then you lose the benefit of Django handling migrations" - but again I might have missed some subtlety here?
For 1. I have found that a custom admin command can go a long way. If you want to be more "reactive" have a look at this asgi/channels thing... That or custom pythons scripts with the caveat of pointing correctly the DJANGO_SETTINGS ...
As for 2. Well... Basically every ORM no ?
I've had the opposite experience, working smoothly with Django for a decade except for one huge Flask project. Which essentially re-built Django... badly.
I later tried and enjoyed Flask for a really small solo project, so I don't think you're wrong.
Maybe there's a lot of implicit cultural knowledge on what packages work best to compliment Flask and the original developers on the big Flask project I suffered chose poorly?
I also used Flask and I wasn't a Django fan. But this got me on larger projects, when Django and his "Batteries Included" made sense. Now I will soon think about the size of the project in advance, and based on that I will choose Django or Flask.
There really is not something wrong here. Everything has its pros and cons.
Right tool for the right job. You’re not wrong unless you are - if as others said you’re reinventing the wheel on flask, or are doing a very simple API service in Django which doesn’t use most of its facilities (like the admin) and could easily be done in flask.
Honestly, I don't see the point of using Flask anymore. You can set up a Django project and just use a single module with a bunch of view functions, built-in testing and sensible defaults. Done. Not choosing that approach just because it takes a few more MBs on disk or needs a few more KBs of memory is shortsighted, IMO. You can't always predict what a project will end up needing.
I'm legitimately asking: why would you use Flask instead of Django, even if you don't (but might) need the ORM, admin etc.? Thanks!
If you don't really know Django, the learning curve on Flask is a lot shallower. So if you don't need ORMs, models, admin etc. but you just want make those python scripts you wrote callable via a web browser then you'll get version 0.1 out the door a lot sooner with Flask.
Also a lot of Django kind of assumes the ORM as your data store. So if you need to use a primary data store that cannot be accessed via the ORM you lose a lot of what Django has to offer.
That being said, I agree that many 'simple' Flask projects have a tenancy to grow until you have implemented most of Django in Flask anyway.
Because Django is pretty badly designed, and it can get in the way when you need to do some more complex stuff. It get's the job done for 95% of cases, but that extra 5% can devolve into some pretty nasty stuff.
Typically the inflection for when Django becomes a nightmare is when you want to start splitting the application up. This is made really hard because Django depends on a whole load of globals (settings, urls, context preprocessors, the actual WSGI handler). With Flask you can have two separately configured applications running in the same process, routed with a bit of WSGI middleware.
This comes in handy when you need to do a 'soft' rewrite and have code running side by side. This also just makes things easier to test, because you can build a new application object for each test with it's own settings. You can't do that in Django with out a great deal of consternation; try creating two tests with different middleware stacks in Django, patching settings won't work because the application has already loaded, and there's no way to reload it between tests.
Also, for the same reason (as someone else said) it makes it tricky to use in non-web contexts. Like Celery.
Django's can't handle more complex database queries. If you've ever seriously used SQLAlchemy, you'll know what you're missing.
The ORM is also lacking a unit of work model, which can kill performance. The only way to create multiple objects in a single database round trip in Django is with `bulk_create`. But you can't create something like a group and then a user in a single database round trip. Sure you can create them in a single transaction, but that's not quite the same, because each roundtrip takes an extra millisecond. It's an easily avoided inefficiency that SQLAlchemy solves.
The template language is limited compared to Jinja2. While this is by design, it doesn't support streaming the response back. This is really annoying if you're generating massive templates. It would have also been really simple to do.
You can use whatever ORM or templating library you want. But at least if one day you realize you need something that Django offers out of the box it's there for you to use.
And if not it's not like it has any perceivable effect on performance.
As a rule of thumb, Flask is good when your app will only ever need to be a single file. Otherwise, as other commenters have said, you're basically reimplementing Django badly.
I feel the same way. I like simple frameworks like Flask, Starlette, or FastAPI. Django feels too heavy for me, though I get why people like it. Maybe I haven't learned it well enough, but I often feel like I'm having to do weird things or fight the framework to get done what I need. Simpler frameworks fit my mental model better.
I owe a lot to Django as it was really the thing that got me into backend programming by leading me to learn python in early 1.X days. My first real programming job was backend django programming for a newspaper. Eventually things shifted towards django-rest-framework, flask, and now my go-to Starlette. Haven't used Django in some time but really appreciate the project and happy to see it moving along.
Congrats on the new job! I never really dabbled with Go, but a team I was on recently worked with a backend written in Go, and I was present in lots of discussions :) For current project I'm using Starlette/asgi, but I'm sure Go would have some advantages
Can you elaborate? I've been using it for years and it mostly does what I want. It's an ORM and obviously sometimes generates unefficient queries I need to manually amend/refactor but otherwise I don't see any major issues with it?
In contrast I've looked at SQLAlchemy with Flask and I couldn't even wrap my head around declaring models (which inherit from the DB connection object if I remember correctly, so potential for circular imports) and manually managing transactions/sessions seems unnecessarily complex.
Comparing Django vs SQLAlchemy, Django's weakest point is its extremely static ORM syntax. The double underscore separation (e.g. user__group__name__icontains) for query parameters is likely my biggest pet peeve as it requires me to unroll unchecked strings together into a big garbled mess. I would have much appreciated being able to use more code-verbose query tools; the moment you have to go into building more dynamic user-defined query systems, Django's ORM just becomes a hindrance.
I also noticed the second part of the comment: Django does a lot of Python magic in the background through extensive use of reflection and class-level declarations, this hides away the abstractions (again) at the propose benefit of ease of use. And well, it is easy to use. For certain applications. I just personally found a lot of footguns trying to work with more advanced Postgres functionality (mainly around JSON) and it took a while to write my own abstractions atop the Django ORM to get to a comfortable level.
The inability to batch network calls in a single unit of work makes the ORM needlessly slow. That's also one of the main advantages to managing transactions/session yourself. It can save a huge number of round trips in a complex view.
The Django ORM itself is also slow at generating SQL. Recently I was bemused by a query, which took 500us to actually be generated. This wasn't doing anything particular wild, it just had a `select_related` call to an object that had about 50 fields (not great DB design, but beyond my control). The query actually took longer to build than it did to run.
That itself wouldn't be an issue if you could LRU cache the SQL query itself. But you can't, it's Django.
You don't take issue with the bizarre and inefficient queries that it often builds? I've observed simple joins implemented using looping by Django ORM... I mean, WTF???
I doubt you're wrong. There's certainly a large set of problem that can be solved equally well by either framework. There are also projects where one is clearly a better solution.
I think if that was ever said by a core member, it was stated as a goal, not a for sure thing. I believe I've only ever heard it as speculation / wishful thinking.
It's a shame that Django's templates are still so bad.
You can't just import and call some arbitrary python function. You most likely need to write a template filter or tag [0]. Maybe there's a good reason for this but it just feels like I'm working around a weird issue in the framework.
Also, I can't use parentheses inside if statements in a template. It's a strange restriction.
I know that Jinja2 -- which is good -- is supported. But it's a second choice, requires some setup and it's not the usual way of doing things.
Don't get me wrong. I like Django and it's still far, far ahead of most other web frameworks. But, because of these issues and also because the frontend story in Django is not that great I find myself reaching for Rails, these days.
It is in fact deliberate, though; the "Philosophy" section on https://docs.djangoproject.com/en/3.1/ref/templates/language... explains it: "If you have a background in programming, or if you’re used to languages which mix programming code directly into HTML, you’ll want to bear in mind that the Django template system is not simply Python embedded into HTML. This is by design: the template system is meant to express presentation, not program logic."
The way I've seen this play out in reality is that a lot of the "presentational logic" required by the templates gets computed in the "Django Views" layer (akin to the "controller" layer in traditional MVC). So in the end Django views both perform business/service logic and presentational logic.
I took it for granted after doing Django for several years but after doing a lot of web development in a more explicit MVC paradigm (Elixir and Phoenix in this case), my old Django code didn't really separate the web layer from the business logic layer. If I write more Django in the future I'll definitely be more aware of this but in many cases the framework (Templates, Forms, Models, Django-apps) don't really encourage this type of in-app architecture.
That's something I think most developers would agree with, I certainly do.
Still, I don't think what I mentioned is unreasonable or goes against the framework's philosophy. The templating system already has plenty of logical statements, might as well make it work like expected.
Basically doubling the complexity of an app. If you need a fair amount of front end interaction, fair enough, but many apps would be a lot simpler with Django templates and a bit of jQuery.
This is one of the reasons why I'm moving to Rails. Frontend work is quite hard with templates and most of the community has moved towards Reactjs because of that, which I don't like.
I think they designed it this way because they assumed that the backend and front developers would be different persons/teams, which makes sense for many projects but for me I'm just a solo dev trying to get work done as fast as possible.
The way Rails does things with ERB makes total sense. DHH himself said that Rails was designed in a way that a single dev can take the framework and build something with it, no teams, no microservices, just plain Rails.
ERB is more dangerous than Django Templates but I like it when a framework doesn't try to protect me from myself.
By what you're saying Rails is indeed gonna serve you well, that's exactly the use case where it shines: small teams that need to move fast.
I also believe it's simple structure is quite good for big projects/teams as well but that's a different discussion.
Jinja is just as bad. They’re both a pain to extend.
I believe firmly in separation of concerns but I have never understood the stubborn stance that there should be little to no logic inside of the template layer.
ERB does it right. I have seen some heinous things there, don't get me wrong, but the freedom to use any part of Ruby is incredible.
Nothing worse than when a client is hoping for a 1 hour fix on a really benign and silly bug - only to find that you'll need most of that time to whip up a custom template filter or tag, jumping through hoops to do all that.
For those of you with a big portfolio of apps, how do you handle framework updates? Scheduled housekeeping once a quarter? Ad hoc? Ignore them until a disaster happens then panic?
I generally develop against django master with loud warnings. Whenever a warning comes up, such as `DEFAULT_AUTO_FIELD` not being specified, or a behavior change such as `SECURE_REFERRER_POLICY`, I go through and apply the same change to _all_ my projects at the same time.
So I'm applying minor changes to multiple projects at the same time as I become aware of the new changes. Once the new Django version comes out, they're basically ready to go live with the new version.
That way I only need to focus on one change at once, rather than one project at a time.
Congratulations to the django team. Having used django for many of my projects for over a decade, it's exciting to see the django community is still going strong and the core members are continuing to push out significant releases such as the 3.2 LTS.
I've been using Django since 2010, I recently hit a roadblock with it that forced me to switch to Go for one of my projects. That's to say, it's not for everything. Especially may not be suitable for advanced SaaS services.
I haven't used Django except as an ORM and it was a terrible experience. Anytime I wanted to update an existing relationship, it was a pain. I've heard a lot of good stuff about it when used as a web framework but I was really baffled by the ORM.
What was so painful about it? Unless you're making some really significant changes to your models, Django's migration commands handle 99.9% of cases including most common edge cases. I can't imagine it being any easier, and certainly haven't seen any other web frameworks handling migrations any better.
I've found the Django ORM to be, in my own opinion, one of the easiest ORMs to hit the ground running with. What was the confusing aspect of updating relational data for you?
Creating relationships was not a problem but for example, adding new fields to an already created many-2-many was an issue. Changing migration scripts was also a hassle.
I have run into this exact problem. A many-to-many table had a business meaning, not just an "invisible" relationship. We wanted to put a model in front of it & add soft deletes and created-at/updated-at fields, at it was a mess of hoops and hacks to jump through.
Does this go easier in any other ORM/DBs that you might have used? Sounds like the semantics of the real-world stuff didn't quite match up to the DB semantics.
We rolled a simple repository pattern library that fit over the SQLAlchemy Table API (no ORM objects, only tables).
Actually writing the the tables was very freeing, no more separation and surprises in the translation between a single model and the multiple tables it can create.
For each new object, we wrote a SQLAlchemy Table object, a domain entity object, and optionally an adapter if you need to map field names between the two. The 300 lines of repo library code did the rest.
A little boilerplate, but no need for a ton of impenetrable, hyper-dynamic ORM code.
Alembic can autogenerate migrations from the SQLALchemy Table objects
I'll post this as a Show HN soon, but I'll mention it now as a soft-launch introduction. After a decade of using Django I started a project I always wanted to exist: backported security and bug fixes to old versions that the Django project has dropped support for.
I've seen many Django projects eventually get stuck on an old version as the team I'm on is forced to defer upgrades in favor of commercial pressures and essential product delivery.
So you can subscribe to https://www.codestasis.com/ to stay patched on your old version, removing the urgency to upgrade. Then unsubscribe when you're caught up.
It's free for personal use and a paid subscription for businesses and organizations.