Puis-je lire des modèles polymorphes à partir d'une seule table de base de données, leur comportement dépendant d'un champ (booléen) du modèle?Comment récupérer un modèle polymorphe à partir d'une seule table dans django - ou comment implémenter un comportement polymorphe dans django
Dans l'un de mes modèles, le comportement est légèrement différent si l'instance est 'avant' contre 'arrière' ou 'gauche' contre 'droite'. Cela conduit à beaucoup de clauses d'if et de duplication de code. Je veux donc avoir une variante du modèle qui retrace les différents comportements.
Mais comment puis-je demander au gestionnaire de modèles de renvoyer les instances des bonnes classes? Dois-je remplacer __init__
du modèle? Peut-être que c'est plus facile à expliquer avec un exemple. Ce que je fais:
class Foo(models.Model):
forward = models.BooleanField()
other_fields = ...
def do_foobar(bar):
if self.forward:
gap = bar.end_pos - bar.current_pos
self.do_forward_move(max = gap)
if self.pos==bar.end_pos:
and so on ...
else:
gap = bar.current_pos - bar.start_pos
self.do_backward_move(max = gap)
if self.pos==bar.start_pos:
and so on ...
Ce que je veux faire:
class Foo(models.Model):
forward = models.BooleanField()
other_fields = ...
def __init__(*args, **kwargs):
""" return ForwardFoo or BackwardFoo
depending on the value of 'forward'"""
How?
def do_foobar(bar):
gap = self.calculate_gap(bar)
self.do_move(max = gap)
if self.end_point_reached():
and so on ...
class ForwardFoo(Foo):
def calculate_gap(bar):
return bar.end_pos - bar.current_pos
and so on ...
for f in Foo.objects.all():
f.do_foobar(bar)
Ou est-il un moyen tout à fait différente pour éviter ce genre de duplication de code?
Super, merci! Je n'étais pas au courant des modèles de proxy jusqu'à présent. Mais ils ne font toujours pas tout ce que je voulais. Je dois toujours utiliser 'ForwardFooManager' et' BackwardFooManager'. Je ne peux pas simplement appeler 'Foo.objects.all()' et obtenir des instances 'ForwardFoo' et' BackwardFoo' en fonction de la valeur de 'forward'. Donc, je laisse cette question ouverte, peut-être que quelqu'un a une idée différente. – jammon
Ce n'est pas possible basé sur comment l'héritage fonctionne en Python, en général, et Django, en particulier. 'Foo' ne retournera que des objets' Foo'. Voir https://docs.djangoproject.com/fr/dev/topics/db/models/#s-querysets-still-return-the-model-that-was-requested –
J'ai peur que vous ayez raison. Je vais reformuler le problème dans une question différente, plus générale. Peut-être que quelqu'un a une idée fondamentalement différente. Merci quand même d'avoir traité ma question un peu longue. – jammon