2 votes

Relations many2many génériques dans Django

Ainsi, j'ai les 4 entités représentées ci-dessous qui sont des entités fortes et indépendantes dans mon application, maintenant le problème est que chaque article ou image pourrait être "étiqueté" avec un présentateur ou un événement, étant donné qu'il s'agit de 4 entités indépendantes qui pourraient devenir plus complexes. Il ne semble pas correct d'ajouter le champ événement et présentateur à la fois à l'article et à l'image ou le contraire, en particulier parce qu'ils pourraient être étiquetés avec aucun.
À long terme, d'autres entités pourraient avoir besoin d'être étiquetées et d'autres entités étiquetables pourraient apparaître.

class Article(models.Model):
    #Fields
class Picture(models.Model):
    #Fields
class Presenter(models.Model):
    # Fields
class Event(models.Model):
    # Fields

Je me rapproche d'une sorte de modèle intermédiaire générique à deux têtes basé sur le type de contenu comme celui-ci (je ne l'ai pas encore testé car il est un peu plus complexe que cela), mais je cherche des idées :

class GenericTag(models.Model):
    # Event,Presenter instance..
    tagcontent_type = models.ForeignKey(ContentType)
    tagobject_id = models.PositiveIntegerField()
    tagcontent_object = generic.GenericForeignKey('tagcontent_type', 'tagobject_id')
    # Picture,Article instance
    objcontent_type = models.ForeignKey(ContentType)
    objobject_id = models.PositiveIntegerField()
    objcontent_object = generic.GenericForeignKey('objcontent_type', 'objobject_id')

Je pense qu'il doit y avoir des moyens plus élégants de faire cela sans remplir tous les modèles de balises en tant que champs dans les modèles balisables.

2voto

Jan Pöschko Points 2492

Une approche différente sans clés étrangères génériques serait d'utiliser l'héritage de modèle :

class Tag(models.Model):
    pass
class Taggable(models.Model):
    pass

class Article(Taggable):
    # Fields
class Picture(Taggable):
    # Fields
class Presenter(Tag):
    # Fields
class Event(Tag):
    # Fields

class TagInstance(models.Model):
    tagged = models.ForeignKey(Taggable)
    tag = models.ForeignKey(Tag)

Cela introduit des tables supplémentaires pour les deux classes de base et des espaces de clés primaires partagées pour leurs instances respectives, afin qu'elles puissent être référencées avec des clés étrangères ordinaires. Cela peut être raisonnable en fonction de ce que vous voulez faire de plus avec vos balises.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X