A community Poll

168 views
Skip to first unread message

Curtis

unread,
Dec 21, 2015, 8:52:21 AM12/21/15
to django-d...@googlegroups.com
Whilst I'm awake... a pull request I made to a 3rd party project
included replacing explicit model imports for relation fields with lazy
binding -- ForeignKey('contenttypes.ContentType') in this case.

The author pointed out this didn't play well with their IDEs refactoring
tool, and asked if there was a general discussion on why lazy references
were better.

So aside from the obvious "preventing circular imports", what other
benefits do people see?

I'm quite sure I was driven to that PR because importing ContentTypes
was causing lots of pain with AppState not being ready.

--
Curtis

Aymeric Augustin

unread,
Dec 21, 2015, 9:09:28 AM12/21/15
to django-d...@googlegroups.com
Hello Curtis,

2015-12-21 14:52 GMT+01:00 Curtis <cur...@tinbrain.net>:
So aside from the obvious "preventing circular imports", what other benefits do people see?

I'm afraid this is an example of "worse is better".

String references to other models in FK definitions are one of the remnants of "Django string magic". Such magic has steadily been removed from Django. I believe the last significant step was to remove the ability to describe views as strings in URLconfs.

I find it best to have a tree of models with as few circular relations as possible. Only relations that "jump back up the tree" should be declared with a string reference to make importing possible. They will usually be nullable (otherwise you could never create such an instance) and also a pain to manage ;-)

I found that this principle helps with the relational design.

-- 
Aymeric.

Carl Meyer

unread,
Dec 21, 2015, 1:02:37 PM12/21/15
to django-d...@googlegroups.com
Hi Curtis,

On 12/21/2015 06:52 AM, Curtis wrote:
> Whilst I'm awake... a pull request I made to a 3rd party project
> included replacing explicit model imports for relation fields with lazy
> binding -- ForeignKey('contenttypes.ContentType') in this case.
>
> The author pointed out this didn't play well with their IDEs refactoring
> tool, and asked if there was a general discussion on why lazy references
> were better.
>
> So aside from the obvious "preventing circular imports", what other
> benefits do people see?

I consider string FK references to be an ugly wart, to be used only when
using regular imports is impossible (that is, only in circular reference
situations).

> I'm quite sure I was driven to that PR because importing ContentTypes
> was causing lots of pain with AppState not being ready.

Hard to say exactly what would be causing that without seeing the
specific case, but it should be resolvable without resorting to string
references. "Fixing" app-registry-not-ready by using string FK
references would feel to me like papering over the problem, instead of
finding the root cause and fixing it.

Carl

signature.asc

Marten Kenbeek

unread,
Dec 21, 2015, 4:41:55 PM12/21/15
to Django developers (Contributions to Django itself)
I'm quite sure I was driven to that PR because importing ContentTypes
was causing lots of pain with AppState not being ready.

Whenever I see this error message pop up, it's not because code directly imports ContentTypes, but because it imports some other models.py module, which in turn imports another models.py module before any class definition is reached. ContentTypes often seems to be the first module without any dependencies. However, it's easy enough to trace the error back to the models.py file that was imported first. Especially when used in a FK, changing it to a string reference won't help, because you're still importing the model with the FK before the app registry is ready. 

For what it's worth, I prefer to import models and use them directly, for no particular reason other than "I like it that way". 

Curtis Maloney

unread,
Dec 23, 2015, 9:32:22 AM12/23/15
to Django developers (Contributions to Django itself)
To clarify a few points:

In general, I'm in favour of removing string references for things... however, when it comes to relation fields, I'm on the side of "alway lazy".

Also, I don't want this discussion to be about my specific issue with contenttypes... more a general "community opinion of best practices"

--
Curtis

Shai Berger

unread,
Dec 23, 2015, 6:43:05 PM12/23/15
to django-d...@googlegroups.com
On Wednesday 23 December 2015 16:32:22 Curtis Maloney wrote:
>
> Also, I don't want this discussion to be about my specific issue with
> contenttypes... more a general "community opinion of best practices"
>
Imports, because of IDE integration and because they make it easier to detect
dependencies.

In a related IRC conversation, Simon (@charettes) and I discussed the issue of
dependencies created by the use of reverse relationships (these do not require
imports, so you don't see them "declared" in the file, but they're very real
dependencies). Simon suggested, as a "best practice", to prevent them by using
`related_name="+"` on FKs to models in other apps. I suggested that this
should be encoded into a new field type.

Shai
Reply all
Reply to author
Forward
0 new messages