Tuesday, September 5, 2017

Re: Dynamic model, reverse foreign key not working

On Tue, Sep 05, 2017 at 03:47:37AM -0700, Roman Akopov wrote:
> Hello,
>
> My problem is very rare so I'll try ad add as much useful detail as
> possible.
>
> I am using python 3.5 and 3.6, Django 1.11.4
>
> I am creating complex security related application and need to generate
> additional models based on other applications' models. In general,
> everything works fine, models are created, migrated without a problem. But
> there is single problem I totally failed to solve.
>
> Let's say there is preexisting model Alpha of some other application and I
> dynamically create model Beta which references Alpha with ForeignKey. The
> problem is that Beta does not get reverse relation, so I can query for
> beta.alpha, but not for alpha.betas. I receive
> "django.core.exceptions.FieldError: Cannot resolve keyword 'betas' into
> field. Choices are: x, y, z"

So the deal is that each model's _meta caches a bunch of structures
storing the list of fields, reverse relations, and so on, the first
time you access any of them. If you add a new field (or a new reverse
relation) after those caches have already been filled, the new field
or relation won't be reflected in them, leading to errors just like
yours.

There's an internal undocumented API that takes care of this,
Model._meta._expire_cache(), which will clear all those caches. It
should do the trick for you, but as always with private APIs, be aware
that it might break or change in the future.

Cheers,

Michal

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/20170905113641.GK8762%40koniiiik.org.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment