Opened 3 years ago

Last modified 3 years ago

#18012 new Cleanup/optimization

Propagate reverse foreign keys from proxy models to base class

Reported by: akaariai Owned by: nobody
Component: Documentation Version: 1.4
Severity: Normal Keywords:
Cc: charette.s@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The idea of proxy model is that the proxy subclass changes behavior, but the base class and all proxy models derived from it (call this "proxy equivalence class") are identical in the database representation. Foreign keys defined to proxy models break this idea:

class A(models.Model):
    pass
class ProxyA(A):
    class Meta:
       proxy = True
class B(models.Model):
    a = models.ForeignKey(ProxyA)

The above code is allowed currently, but A does not have a reverse relation to B, while ProxyA has that. It would be nice from maintainability perspective to have exactly same field set for every model in the proxy equivalence class. In addition, adding the reverse relation to the equivalence class would make the database representation equivalent to the Python representation.

Change History (6)

comment:1 Changed 3 years ago by carljm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted
  • Type changed from Uncategorized to Cleanup/optimization

comment:2 Changed 3 years ago by charettes

  • Cc charette.s@… added

comment:3 Changed 3 years ago by Alex

It doesn't seem correct, IMO, for A to have the FKey reverse descriptor on it.

comment:4 Changed 3 years ago by akaariai

The main point here is that in the DB representation A has b_set (there is a foreign key from B to A).

The original problem IIRC was that some users want to use the foreign key to proxy model so that they can get proxy model instances instead of the concrete class instance (auth.User was the use case, again IIRC).

The foreign key to proxy class doesn't make sense from data modeling perspective (there really can't be a foreign key to proxy class in the DB layer). It is a hack to get the related models as a proxy class. Now, if there was an easy way to achieve retrieval as proxy, then the whole FK to proxy could be deprecated (unless I am missing some other important use case). Whole another matter is that I don't have any idea what that API might be. You would need to handle select_related, prefetch_related, and fetch through attribute at least.

Still, I have no need to change the current behavior. Should I just close this ticket?

comment:5 Changed 3 years ago by charettes

IMHO when I explicitly create a FK to a proxy model I expect the current behaviour. Maybe we should just document this?

Last edited 3 years ago by charettes (previous) (diff)

comment:6 Changed 3 years ago by akaariai

  • Component changed from Database layer (models, ORM) to Documentation

Seems like I am in the opposition here. So, lets not change the current code.

Note: See TracTickets for help on using tickets.
Back to Top