2017-10-02 6 views
1

J'essaye de concevoir un fil de discussion dans Django. Les utilisateurs peuvent publier des threads, des réponses aux threads ou des réponses à d'autres réponses de thread (comme dans les commentaires Reddit). Tous les messages partagent des informations de base comme la date et l'auteur, donc je pensais que je ferais un Post classe abstraite. Étant donné que tous les messages peuvent avoir un poste parent qu'ils répondez, mon intuition était d'essayer de définir la classe abstraite:Django Model - Classe abstraite avec Self Relationship

class Post(models.Model): 
    content = models.TextField(max_length=1000) 
    parent = models.ForeignKey('self', null=True) 
    createdBy = models.ForeignKey(User) 
    class Meta: 
     abstract = True 

class Thread(Post): 
    title = models.CharField(max_length=200) 

class ThreadReply(Post): 
    score = models.IntegerField(default=0) 

Mais le résultat est que la classe enfant ne peut avoir un parent du même type, tandis qu'un ThreadReply devrait vraiment être en mesure d'avoir un parent qui est un Thread OU un parent qui est un ThreadReply. Une solution est si je les relations en définir ThreadReply:

class Post(models.Model): 
    content = models.TextField(max_length=1000) 
    createdBy = models.ForeignKey(User) 
    class Meta: 
     abstract = True 

class Thread(Post): 
    title = models.CharField(max_length=200) 

class ThreadReply(Post): 
    score = models.IntegerField(default=0) 
    parentThread = models.ForeignKey(Thread,null=True) 
    parentReply = models.ForeignKey(ThreadReply,null=True) 

Mais cela ne me sens pas ... assez orienté objet? Cela me dérange que chaque objet ThreadReply aura une relation gaspillée, comme fonctionnellement il peut seulement être une réponse à un Thread, ou un ThreadReply.

+2

Jetez un oeil à [relations génériques] (https://docs.djangoproject.com/fr/1.11/ref/contrib/contenttypes/#generic-relations) – dahrens

+0

Oui, les relations génériques semblent être le moyen, merci. Je mettrai à jour le post avec ma solution de relation générique quand je l'aurai fonctionné. – stackPusher

Répondre

0

Grâce au commentaire de Dahrens j'ai regardé dans Generic Relations et j'ai trouvé ce dont j'avais besoin. Il ne comportait changer l'héritage de telle sorte que la classe parente est plus abstraite:

from django.contrib.contenttypes.fields import GenericForeignKey,GenericRelation 
from django.contrib.contenttypes.models import ContentType 

class Post(models.Model): 
    content = models.TextField(max_length=1000) 
    createdBy = models.ForeignKey(User) 
    score = models.IntegerField(default=0) 
    content_type = models.ForeignKey(ContentType,on_delete=models.CASCADE,null=True) 
    object_id = models.PositiveIntegerField(null=True) 
    parent = GenericForeignKey(content_type,object_id) 
    replies = GenericRelation('Post') 

class Thread(Post): 
    title = models.CharField(max_length=200) 

Maintenant Post est utilisé pour les réponses de fil et le fil se prolonge juste. Post a une relation 'parent' polymorphe qui peut accepter un Thread OU un Post.