
Django 1.11 Released - andrewingram
https://www.djangoproject.com/weblog/2017/apr/04/django-111-released/
======
theptip
My main point of friction in Django is still the admin interface; it's got a
very steep sigmoid of a learning curve. The easy stuff is very easy, which is
great, but when you want to do something somewhat complex it becomes arcane
very quickly, usually requiring step-debugging through the code to figure out
which framework method needs to be tweaked.

Also, it's 2017 and we are still selecting ForeignKeys from an unfiltered
drop-down menu with potemtially thousands of entries? This is madness. A PR
for using select2.js
([https://github.com/django/django/pull/6385](https://github.com/django/django/pull/6385))
has been floating around for a year now, but progress is glacial.

I fear the admin site code has become so flexible and generic that it's
difficult to extend, which is discouraging improvements.

Anyone care to shout out their favourite admin site replacements? I've tried a
few but not found a great fit.

~~~
victorhooi
There was a discussion a few years ago about revamping/updating the Django
Admin - but I don't think it got much traction:

[https://groups.google.com/d/topic/django-
developers/Vozu6U3g...](https://groups.google.com/d/topic/django-
developers/Vozu6U3gz84/discussion)

My understanding is it's not something they care enough about yet to fix - or
it's too hard/expensive.

UPDATE: Also found this blog post from one of the core devs/founders:

[https://jacobian.org/writing/so-you-want-a-new-
admin/](https://jacobian.org/writing/so-you-want-a-new-admin/)

~~~
theptip
> The admin may look simple on the surface, but it’s shockingly complex and
> represents a ton of work.

This matches my experience. I can't escape the feeling that 90% of that
complexity is irrelevant at best, and counterproductive at worst, for my
current use-case -- but I haven't quite mustered the bravery to write my own
custom admin site for my app.

I wonder if DRF's CoreAPI schemas would make this easier, since you can now
auto-generate a JS client for your API models, so you just need to wire up
routers and views for your CRUD.

~~~
sametmax
It's not. Every template, every view, every form can be overriden. And all of
them have hooks on the admin config class to handle simple customization. The
software internal is quite amazing and uses all Django's features in the book.

~~~
collinmanderson
> uses all Django's features in the book.

Also, I think the admin traditionally has been a good driving force for
feature improvement.

------
rattray
The new index definitions look nice:

    
    
        from django.db import models
    
        class Customer(models.Model):
            first_name = models.CharField(max_length=100)
            last_name = models.CharField(max_length=100)
    
            class Meta:
                indexes = [
                    models.Index(fields=['last_name', 'first_name']),
                    models.Index(fields=['first_name'], name='first_name_idx'),
                ]
    

Also supports ordering (eg; `'-first_name'` for DESC) and
`BrinIndex`/`GinIndex`.

~~~
ddorian43
Damn, those are new ? Or did just the formating change?

~~~
ubernostrum
Bit of both.

Previously, you could indicate you wanted an index on a field, but only on a
single field, and you did it in the field definition.

Declaring them in Meta via the Index class is new, as is the multi-field
support and direction support. More importantly, you can subclass Index to
define other types of indices besides the default (which is btree). For
example, Django now ships built-in subclasses to do BRIN and GIN on Postgres.

~~~
deckiedan
Is there anywhere django docs on how to actually use the brin/gin indexes? All
I can find is that they exist...

~~~
rattray
[https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/...](https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/indexes/#module-
django.contrib.postgres.indexes)

------
RicCo386
Last major release before Django 2.0 which will be Python 3 only. Looking
forward to the __future__

~~~
cheapsteak
I've been meaning to learn Django as it seems to have a much more mature ORM
and migration capabilities (currently very much productive with node via
Sequelize and Express, but migrations are rather tedious). Is now a good time
or should I wait till 2 is out? How big of a break will it be?

A friend also expressed that it might not be worth it to use Django if just
for the ORM and migrations (backend is just api), is he right?

~~~
thehardsphere
> How big of a break will [Django 2.0] be?

Not abnormally big at all if you're writing Python 3 code. The Django team is
very good at communicating about planned changes in advance. Aside from
dropping Python 2 support, the only reason they're calling it Django 2.0 is
because they switched version numbering schemes to a modified version of
SemVer.

I would learn now if I were you.

> A friend also expressed that it might not be worth it to use Django if just
> for the ORM and migrations (backend is just api), is he right?

I'm not sure, because I don't know what the alternatives are for you (I dabble
in Django on the side). But I do know that some people do use parts of Django
instead of all three layers, so it may not be ridiculous.

~~~
cheapsteak
What is your main stack?

~~~
thehardsphere
Java EE et al. Specifically Spring/Hibernate in a web app that we distribute
to customers for them to run themselves (usually in Tomcat). With a separate
UI app that is finally almost finished transitioning from Flex to Javascript.

Not the sort of thing I recommend unless you have an application that actually
needs all of that (which our users do, and if you did I doubt you'd be looking
at anything in Python).

------
ploggingdev
As soon as I saw this post, I upgraded a project from Django 1.10.5 to Django
1.11 using this guide [1] and faced no issues at all. Deprecation warnings are
displayed, but that's because third party packages need time to update. Great
work Django devs!

[1] [https://docs.djangoproject.com/en/1.11/howto/upgrade-
version...](https://docs.djangoproject.com/en/1.11/howto/upgrade-version/)

~~~
tclancy
If you want to upgrade from further back but are worried about it, I put
together a guide to the biggest changes at each step from 1.3 on:
[http://thosecleverkids.com/thoughts/posts/upgrading-
django](http://thosecleverkids.com/thoughts/posts/upgrading-django)

------
ubernostrum
Unsure why the comment pointing this out is dead, but yes: this is the last
release series of Django to support Python 2. The next major release of Django
will be 2.0, which introduces a new release cadence and will only support
Python 3.

For those who are curious and don't feel like digging into the release-process
documentation, the new system will consist of three point releases per major
version. So 2.0, 2.1, 2.2, then 3.0, 3.1, 3.2, and so on.

Each X.2 release will be an LTS. Compatibility policy will be that if you're
running X.2, and get no deprecation warnings, you can upgrade direct to
(X+1).2 without changing any code. Then when you clear any deprecation
warnings that pop up post-upgrade, you're good to go for (X+2).2.

~~~
emidln
Any pointers to documentation / discussion around the rationale for X.2
instead of X.0 or X.1? I'm sure there are very good reasons and would like to
read them.

~~~
robertfw
I haven't seen it discussed but immediately it would appear that it would
allow for new features introduced in x.0 to have the kinks worked out in the
x.1 and x.2 releases, so the LTS ends up having the new features along with
their fixes, and then you can move on to the next batch of bigger features

------
cdnsteve
LTS release, now I can assure business that we're good on this technology
stack for 3 years. Thanks Django team!

~~~
sbuttgereit
You know, when I look at their statement about this being an LTS, it seems (to
my understanding) that they have a slightly different definition of what
support means in this context.

" _This version has been designated as a long-term support (LTS) release,
which means that security and data loss fixes will be applied for at least the
next three years. It will also receive fixes for crashing bugs, major
functionality bugs in newly-introduced features, and regressions from older
versions of Django for the next eight months until December 2017_ "

I expect that something like a "crashing bug" would be something that would be
supported in an LTS, but here they're specifically excluding such bugs from
the full three year duration. If stability were a priority, I'm not sure I
would look at this any differently than an 8 month release.

To be fair, I don't work in this space, so I may have a skewed perspective,
but the 8 month limitation items did catch me off guard.

~~~
jldugger
If you require longer support, you probably want to pay for such a thing. Does
RHEL package django?

~~~
collinmanderson
It's in EPEL.

Also, Django 1.11 will likely be in Ubuntu 18.04, supported until 2023.

------
nik736
Anyone interested in explaining why I should choose Django over Rails
nowadays? Or is this just a Python vs Ruby thing?

~~~
cookiecaper
I recently posted about why I dislike Rails. For a long time, I also disliked
Django, for somewhat similar reasons. [0]

The _biggest_ thing that I disliked about Django was its templating system.
Its attempts to magically render values were (and are) offensive. When I
looked before, just like Rails, it was take it or leave it, and there was
little sympathy for making it pluggable.

Such issues, and the culture's Rails-like resistance to outside suggestion and
interoperability, pushed me into Pylons/Pyramid.

Today, I think Django has improved a lot, and I don't think it's fair to
continue to lay the pox of being "Rails-for-Python" on it.

Django now supports third-party templating engines (so the dealkiller is gone)
and last I checked, the SQLAlchemy integration, while not official, is much
better. They now have Python 3 support and as pointed out here, will be going
Python 3 exclusive soon.

I've submitted a few bugs and they get triaged quickly. I had a patch or two
merged. Pretty happy with that. The Mezzanine guy is also great about this
stuff.

Django does follow the old-school big magic model, but I haven't encountered
much [recent] trouble in working around that. The community does not seem to
respond negatively to such suggestions anymore.

People say it comes down to Ruby v. Python, and I think that's true, but in a
different way than most. It comes down to the _core culture_ of Ruby v.
Python.

As the MVC framework hype and subsequent noob-influx died down, Django was
left with the core Python community of mature hackers who've developed a
refined palette for simplicity. This has been Django's biggest asset, and has
turned it into something that's worth using today.

Disclaimer here: I was not then, and I am not now, super deeply involved in
Django, either the product or the community. This is primarily based on my
impressions from light observation and use. Some/much of it could be wrong.

[0]
[https://news.ycombinator.com/item?id=14015270](https://news.ycombinator.com/item?id=14015270)

~~~
jldugger
> The biggest thing that I disliked about Django was its templating system.
> Its attempts to magically render values were (and are) offensive. When I
> looked before, just like Rails, it was take it or leave it, and there was
> little sympathy for making it pluggable.

Templating is the most frequently subbed out part of Django. I'm not sure how
you'd make it more "pluggable."

~~~
rtpg
They made it so that you could still use django's "render helpers" and things
like the middleware directly, and just replace the 'render the template file'
part.

Before you could always call a third-party rendering library, but it usually
meant you wouldn't get things like the Django context renderers or template
file lookup by default

------
mxscho
Note that 1.11.x is also the last major version to support Python 2.7, 2.0
will only run on Python 3.5+ iirc.

~~~
TkTech
I imagine the last major _official_ version. There are so many companies still
stuck on 2.7 for various reasons that features will be forked and backported
for at least 5 more years.

~~~
publicfig
Well, this is an LTS release, so it will be supported until 2020. By 2020,
however, not only will Django 1.11 have reached End of Life, but Python 2.7
itself will have as well. Any company concerned with using a Django version
past EOL will also have the same issue of supporting Python 2.7 past EOL

~~~
collinmanderson
Also, if a company is still stuck on Python 2.7 in 2020, there's a good chance
probably already stuck on an older version of Django anyway.

------
andrewingram
Quick link to release notes:

[https://docs.djangoproject.com/en/1.11/releases/1.11/](https://docs.djangoproject.com/en/1.11/releases/1.11/)

------
swah
If I'm consuming from an API instead of interacting with Postgres, does it
make sense to use Django instead of something without "models" ?

~~~
mkolodny
I'd highly, highly recommend Django REST Framework: [http://www.django-rest-
framework.org/](http://www.django-rest-framework.org/)

It's built on top of Django, and makes creating APIs super easy.

~~~
swah
Ok, I'm actually looking at that for the last few days, but would make the
same question replacing Django with DRF.

~~~
theptip
I'd argue that for anything other than a very simple microservice that is
going to remain static, DRF is the better choice. Its sweet spot is simple to
moderately complex domain models, particularly CRUD-based APIs, where you get
a _lot_ for free.

It's great to be able to define a DB model, and in a few lines of code have
the API endpoint for that DB entity up and running.

When you start getting to complex apps, you may find yourself fighting against
the framework somewhat in order to keep your concerns separated, but that's a
Hard Problem in general, and so I don't think it's a flaw of the framework
itself (though there are a few areas where DRF is opinionated that I think it
should not be). If you were using Flask, you'd have more freedom to tweak
things when you get to this point, but you'd also have spent 1.5x the dev
effort building all of the things that Django/DRF does already.

In short, if you don't know whether you need Django/DRF or Flask, you probably
need Django/DRF. Once you have enough experience with Django/DRF to critique
that stack's design decisions, you'll be in a position to make good decisions
of your own with Flask if Django/DRF doesn't meet your needs.

~~~
swah
Another bit of "FUD" I have is that I always consider the database (pgsql say)
to be the one thing that won't change, so I create tables in SQL and would
keep that even if the service changed from say Python to Go.

With Django, would I be able and would it make sense to keep the SQL schema if
I changed languages?

~~~
theptip
I've not used SQLAlchemy much, but I assume it can be configured to map onto
the DB tables that Django has created.

Django has the concept of `apps`, where each app gets its own namespace. So
for model `foo` in app `app1`, you get a table `app1_foo`. Inside that table
it's just the standard SQL columns that you'd expect. So you might need to
override the default table name if your new ORM provides one, but no more than
that.

The only other piece that might give you grief is the ContentType machinery;
there's a content_type table that has a row for each model class, which lets
you do generic foreign key lookups. It might be some work to duplicate that,
if you start depending on it. But it's not super-complex; it's just <id,
app_label, model> in that table.

------
truetuna
It's been a while since I've used Django but at the time (I think 1.6) I
couldn't figure out a way to do a migration like adding a non null column to a
decent sized relation 100M records without having the table lock up.

I use flyway now for db migrations and what's great is that I can perform
migrations in multiple steps (because it's just SQL). So in this case, I can
alter table and add a column with nullable, deploy my app to write to both,
migrate data at a later time, deploy app again to stop writing to the old
column, update column constraints and remove old column.

Does Django ORM have this kind of flexibility?

~~~
odonnellryan
Yeah you can write raw SQL with Django ORM or in the migrations.

------
cutler
Can someone explain the results of recent Techempower benchmarks
([https://www.techempower.com/benchmarks/#section=data-r13](https://www.techempower.com/benchmarks/#section=data-r13))
which show Django 22 times faster than Rails for JSON serialisation, 4 times
faster for multiple queries, 7 times faster with fortunes and 23 times faster
handling plain text? If these results were true wouldn't Django have replaced
Rails long ago?

~~~
MaxfordAndSons
Because if raw performance is your main selection criteria for a web framework
you shouldn't be using either of them.

------
bachstelze
Are there plans for django 2.0 to support asynchronous processing like in
[http://aiohttp.readthedocs.io/en/stable/](http://aiohttp.readthedocs.io/en/stable/)
? Everybody suggests celery as an asynchrone task queue, but i dont see how to
resolve a http request with it. Will this come with python 3 because the
async/await syntax introduced by PEP 492 is only valid for Python 3.5+ ?

~~~
fleetfox
And why would you want it? What is your use case? Making something async
introduces a lot of complexity with no obvious benefit. It's also not as
simple as it looks. For instance all db access in django is synchronous at the
moment and changing that is not trivial since it requires swapping out whole
layer.

I don't read the mailing lists but i'm not sure if it's even considered.

If you want async requests today you can take a look at channels:
[http://channels.readthedocs.io/en/latest/](http://channels.readthedocs.io/en/latest/)

~~~
bachstelze
I want to return values from external REST APIs to the client. Is it really
that hard with the new async/await syntax?

------
mundanevoice
Best Django release ever! Good thing we have 1 years overlap between two LTS
releases (1.8 and 1.11). Will be upgrading my apps soon. :D

------
jamesmp98
I'm surprised Django is still alive given the recent JavaScript-everything-
must-be-a-client-webapp hype.

~~~
AdamN
No biggie. We use Django Rest Framework to drive the API on top of Django and
React as the front-end single page web app. Works great!

------
wenbert
Does Django have an equivalent for Laravel's Homestead?

~~~
dguaraglia
Not sure that's really necessary with Django. Lavarel, like most PHP
frameworks, require an HTTP server configured with just the right version of
PHP, etc. just for development. Django is much simpler:

\- django-admin startproject MyProject \- cd MyProject \- python manage.py
migrate \- python manage.py runserver

That should give you a very decent development server without requiring
VirtualBox or anything like that. I'd recommend following the official
tutorial if you want to give it a spin.

~~~
GoodbyeEarl
I've realized last week these simple steps to run a Django project, but, as I
come from Node, I miss npm start.

~~~
abdelhai
Why not use a Makefile or Invoke (written in Python) to achieve this?. That's
what I have been doing.

------
alexbecker
They seem to be moving towards saner form rendering [0], which is nice. And
they fixed at least one of their numerous footguns [1]. But I still think
Django has too many footguns to be used for important projects [2].

[0]
[https://docs.djangoproject.com/en/1.11/ref/forms/renderers/](https://docs.djangoproject.com/en/1.11/ref/forms/renderers/)

[1]
[https://docs.djangoproject.com/en/1.11/releases/1.11/#querys...](https://docs.djangoproject.com/en/1.11/releases/1.11/#queryset-
get-or-create-and-update-or-create-validate-arguments)

[2] [https://alexcbecker.net/blog.html#django-is-
terrible](https://alexcbecker.net/blog.html#django-is-terrible)

~~~
tedmiston
It's great that you've written a thoughtful critique about such nuanced and
valid points, but from reading your post, it's not totally clear to me what
you think are viable solutions to making (1) requests more atomic and (2)
validation more intuitive.

Regarding (3) testing complex dynamic templates, I don't have much input as I
tend to build APIs using Django Rest Framework rather than web apps with
Django templates. Perhaps serializers and validators in DRF solve some of your
concerns.

(I'd also be curious to hear what frameworks or libraries you've opted to use
instead of Django for your use cases.)

~~~
alexbecker
I think making requests more atomic is pretty easy, if a bit painful--just
make ATOMIC_REQUESTS=True the default, and rewrite get_or_create to occur in a
transaction and perform a second get if it creates a new object, then rollback
the transaction if more than one object is returned and use the other object
instead (similarly rewrite update_or_create).

I agree intuitive validation is harder. I think it would be a vast improvement
to separate the parts of the validation that are form-only from the ones that
are actually database constraints, e.g. in a form_validation kwarg, because in
my experience half the problem is that developers aren't _aware_ of what's
happening on the form vs the database. They could also add some of the
validation that is currently on forms to the database via CHECK constraints.
And they could also do validation in model setters, not allowing a model
attribute to be set to a value it wouldn't accept via forms.

I have used DRF, and I find the serializers and validators quite easy to work
with. My complaint only complaint with DRF is that, at least at the time when
I used it 1-2 years ago, it was annoyingly easy to accidentally expose more
fields for writing than one intended--in fact my first exposure to it was
frantically fixing a bunch of security vulnerabilities I discovered in an API
written using it.

For other frameworks, I have used Flask+SQLAlchemy (Core) and found it a lot
better than Django. Like any good framework grump I am also developing my own,
which avoids all of these problems in exchange for what I'm sure are a host of
problems I haven't considered.

