Circular dependency in forms+views+models

511 views
Skip to first unread message

Jorge Cardoso Leitao

unread,
Sep 1, 2013, 3:00:52 AM9/1/13
to django-d...@googlegroups.com
The way I stumbled across this problem was:

1. views imports models and forms (both are normally needed)

2. forms imports models (for ModelForm)

3. models imports views (for get_absolute_url), e.g.:

import views
class MyModel(models.Model):
get_absolute_url(reverse(views.myview))

which leads to a circular dependency of the form views->forms->models->views.

I searched and there are some questions raised in stackoverflow about it, e.g. thisthis.
This is avoided by removing one of the imports, and in this
case the candidate is 3., replacing it with a string (e.g. 'views.myview').

I propose that we add a note on the documentation of get_absolute_url
explaining that get_aboslute_url should be coded by returning reverses of strings and
not of functions or classes to avoid circular dependencies.

There is a ongoing thread about get_absolute_url and I think these problems are
somewhat related: this circular dependency is a valid mistake from a
Django user because models are depending on views, views on forms, forms on models.

Another reason why I think this should be documented is that circular dependencies
are difficult to debug, specially when they occur after modules are imported like import module.

This also makes the documentation more consistent: Foreign Key already warns about circular dependencies:

"This sort of reference can be useful when resolving circular import dependencies between two applications."

In summary, I agree that the url's "anti-circular dependency" is correctly fixed from the implementation point of view by allowing strings,
what I'm proposing is just to document why users should use it, i.e. what they are useful for, specially in the models' get_absolute_url.

If no one objects, I can do this.

Regards,
Jorge

Curtis Maloney

unread,
Sep 1, 2013, 3:22:37 AM9/1/13
to django-d...@googlegroups.com
Given both the docs for get_absolute_url and reverse demonstrate using string references only, I think adding in clarification of why it's preferred is worthwhile.

I still find it surprising how often I need to tell people on #django to not import models just to reference them in relation fields...

--
Curtis



--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
For more options, visit https://groups.google.com/groups/opt_out.

Marc Tamlyn

unread,
Sep 2, 2013, 5:53:29 AM9/2/13
to django-d...@googlegroups.com
I think the main issue here is using the view (name OR instance) as the reference. We really should be pushing naming of urls more in the documentation - they're always mentioned but as a "you might prefer to do this" rather than a "use URL names on every URLpattern and in reverse. You could also use these other methods."

The tutorial is now quite good at following these best practices, but the reference docs are not.

Russell Keith-Magee

unread,
Sep 2, 2013, 9:37:37 AM9/2/13
to Django Developers

I agree with Marc -- the fix here is that you should be using a named URL, not referencing the view directly. The circular dependency shouldn't exist - it should be broken by the dereferencing provided by the URL name. This is a feature that was added late in the development of Django (well… relatively. Pre 1.0, but after all the core had been laid down), so the docs haven't been completely updated to reflect this.

Yours,
Russ Magee %-)

Marc Tamlyn

unread,
Sep 2, 2013, 9:40:20 AM9/2/13
to django-d...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages