I'm using django for more than 10 years, phoenix for like 4. I consider myself experienced in both frameworks. I wanted to write some blog post about my experience with them, but never found the time.

In any case, Phoenix is a fine (niche) framework but can't really be compared to a masterpiece like Django:

* Phoenix, probably because of its influences from the ruby world is using some concept called "generators". Using the generator it will generate (sometimes a lot) source code files that will implement some functionality. For example, let's suppose you create a new schema (similar to the django model concept). You can use the generator so it will automagically create code for the schema file, its migratinons, some crud forms and even tests. This works fine until you need add another field to your schema, or you need to rename a field or just do a small mistake! Then you'll need to do some very error-prone and boring work. Compare this to the way that Django uses the Model to generate everything from that using class inheritance and composition, without the need to write any code. Also notice that the phoenix generators can't understand relations and you need to edit the schema and migration files by hand to properly add references.

* No auto-migraton support. That's that. If you add a field to a schema you need to edit the migrtion file yourself. Django automagically understands the changes and will generate the migration file.

* This generator thing unfortunately has influenced various other stuff from phoenix, like authentication (you use generators to create some kind of authentication code which then you need to edit). Again, compare this to the elegance of Django using the authentication backends. Also you use generators for presence, channels, whatever...

* The "ORM" (which is not really an ORM it's more or less a way to talk to the DB called ecto) is miles behind the Django ORM. It doesn't support any andvanced stuff, you need to do the joins yourself (i.e from(u in User), left_join: (a in Authority), on: a.id = u.authority_id, where: u.is_active == true. Compare that to User.objects.filter(is_active=True).select_related('authority').

* Also the ORM doesn't support most of the advanced stuff and you need to use an escape hatch called "fragment" that allows you to write raw SQL.

* Phoenix has no django admin. nuff said.

* The phoenix has some funny controller/view/template architecture (which I also think that was influenced from rails) that isn't very intuitive. The views are more or less useless and everything is like router -> controller -> template. Similar to urls -> views -> template in Django. But having the unnecessary views there adds another level of abstraction making everything more complexfor no reason.

* Things like template inheritance are not really possible in phoenix. You use a thing called layouts to re-use stuff. The Django template inheritance is much, much more powerful and simple to understand.

* Django is much more batteries included: Phoenix has more or less no authentication (beyond the generator generated one I mentioned before), no caching framework (you need to use some kind of extension), no pagination support (!), no permissions and various other things that you'll need to implement yourself or find some obscure library that has 3 years to be updated and doesn't suport the latest phoenix, which gets me to the next point:

* Phoenix needs a JS bundler for its javascript code. It used to use webpack and now uses esbuild. Still, they could just provide the proper compiled JS files and let us decide if we wanted to use any node-js stuff (which I avoid like hell).

* Re-using code among controllers is possible using plugs but definitely not as straightforward as extending class based views with mixins.

* The ecosystem is very very small. Most libraries/extensions are 1 person projects and most of these are from persons that tried phoenix for a project but moved on so they are unmaintained. I remember that there was the "default" pagination library in phoenix (scrivener) and it didn't support the latest phoenix for like 2 years? People had to use a fork instead.

* Better support and much easier updates. Because of the huge different in users, when you have any problem with django you're going to easily find answers on line. Also because Django is more mature and much more eyes look at its release candidates, it will be much easier to update to new versions. I've got apps that started from Django 1.6 and now are at 3.2.

* The documentation of phoenix is not bad but it can't be compared to the django docs.

Yes I know that until now I only told bad things about Phoenix but it's my experience and especially when trying to compare it with something definitely better. However I have used phoenix in a couple of specific projects and these were sucesfull. My opinion in that phoenix is not a general purpose framework but a niche one. When you have some specific requirements then yes phoenix would be a fine solution. These requirements are real-time updates using websockets. It's exactly the niche that Django (and python is general) is not good.

Phoenix, because of elixir (and erlang) is great on supporting small processes that can be used to implement quick real-time communication between clients and server so as to implement apps like chat servers, online games, broadcast communication server etc i.e when your http clients open a websocket and send/receive real-time updates to the server.

To enhance that even more, phoenix has a technology called Liveview that makes all this stuff even easier because it allows you to do client-side updates from the server side so as to keep JS to a bare minimum; instead of using react in your client side you keep all your app server side. This is a revelation and a much better way to work than using the client side JS framworks. This probably is the reason that Phoenix is loved so much more.

Please notice that I didn't compare Elixir/Erlang vs Python. Elixir can be used to create some stuff that can't be done in Python (i.e using processes to schedule or queue stuff etc) but these are not Phoenix/Django related stuff.

Sorry for the long comment, I guess I should have written the blog post ...