2017-07-22 7 views
0

Ich bin mit Django herumspielen versuchen, mehr zu lernen und ich bin ein bisschen eine Straßensperre mit Verständnis für das Modell Design. Ich versuche eine App zu erstellen, die wie die Facebook "Wall" ist, aber es sind reine Alben mit Fotos und Videos, mit Kommentaren und Stimmen. Mein Kampf besteht darin, zu verstehen, wie man die Beziehung für Dinge gestaltet, die viele Beziehungen haben können. Als Beispiel können Sie Fotos, Videos, Kommentare, Alben und was auch immer verbessern. Was ist der geeignete Modellentwurf, um nichtspezifische Artikel zu behandeln? Hier ist meine vorgeschlagene Struktur bisher.Django Model Design für "Wall" -type app

Album --primary 
--id 
--datetime 
--created by 
--title 
--photo(s) 
--comment(s) 
--+1(s) 

photo 
--id 
--foreignkey album 
--datetime 
--uploaded by 
--caption 
--comment(s) 
--path 
--+1(s) 

video 
--id 
--foreignkey album 
--datetime 
--caption 
--comment(s) 
--path 
--+1(s) 

comments 
--id 
--user 
--datetime 
+1(s) 


+1s 
--id 
--user 

Antwort

1

Klingt wie Sie eine GenericForeignKey wollen:

https://docs.djangoproject.com/en/1.11/ref/contrib/contenttypes/

Das Content Modell, das Sie etwas suchen

Es wäre wie diese

from django.db import models 
from django.contrib.auth.models import User 
from django.contrib.contenttypes.fields import GenericForeignKey 
from django.contrib.contenttypes.models import ContentType 

class Upvote(models.Model): 
    user = models.ForeignKey(User) 
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 
1

Sie‘machen können Suchen Sie nach GenericForeignKey, example:

class Vote(models.Model): 
    class Meta: 
     db_table = "votes" 
     index_together = [ 
      ["content_type", "object_id"], 
     ] 

    # The following 3 fields represent the Comment or Post 
    # on which a vote has been cast 
    # See Generic Relations in Django's documentation 
    content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 
    voter = models.ForeignKey(User, on_delete=models.PROTECT) 
    type_of_vote = models.IntegerField(choices = (
      (UPVOTE, 'Upvote'), 
      (DOWNVOTE, 'Downvote'), 
      (FLAG, 'Flag'), 
     )) 
    submission_time = models.DateTimeField(auto_now_add=True) 

Hier Content Modell darstellen und speichern Informationen über die in Ihrem Projekt installiert Modelle (Album, Foto, Video ...) und neue Instanzen von Content werden automatisch erstellt, wenn neue Modelle installiert sind.

Jetzt müssen wir den Foreign Key nicht mehr für andere Django-Modelle verwenden, die wir verfolgen möchten. Mithilfe der GenericRelations können wir diese Stimmen nun für jedes beliebige Modell erfassen, ohne das Vote-Modell ändern zu müssen.

Die umgekehrte Beziehung wird der Teil der Modelle sein, den wir verfolgen müssen. Zum Beispiel:

class Post: 
    ... 
    ... 
    votes = GenericRelation(Vote) 
    ... 
    ... 

class Comment: 
    ... 
    ... 
    votes = GenericRelation(Vote) 
    ... 
    ... 

Wenn wir nun einen wenig Gedanken zu unseren bestehenden Post und Comment-Modelle setzen, würden wir beobachten, dass die beiden Modelle sollten mehr oder weniger in der gleichen Art und Weise verhalten. Zum Beispiel können beide Up-, Down-, Flag- und Unflagging-Funktionen verwendet werden und sollten dafür Schnittstellen zur Verfügung stellen.

Daher können wir eine Basisklasse für sie als Votable erstellen und die gemeinsamen Verhaltensweisen und Attribute dazu schieben. Der Post und der Kommentar sind dann konkrete Klassen und erben von Votable.

class Votable(models.Model): 
    """ An object on which people would want to vote 
     Post and Comment are concrete classes 
    """ 
    class Meta: 
     abstract = True 

    votes = GenericRelation(Vote) 
    author = models.ForeignKey(User, on_delete=models.PROTECT) 

    # denormalization to save database queries 
    # flags = count of votes of type "Flag" 
    upvotes = models.IntegerField(default=0) 
    downvotes = models.IntegerField(default=0) 
    flags = models.IntegerField(default=0) 

    def upvote(self, user): 
     .... 
     .... 

    def downvote(self, user): 
     .... 
     .... 

class Post(Votable): 
    # post specific implementation 
    ... 
    ... 

class Comment(Votable): 
    # comment specific implementation 
    ... 
    ... 

Source

more info

+0

Viele gute Infos und Bezug hier. Was passiert, wenn ich etwas zweimal unterklassifiziert habe? Wie kann ein Foto kommentierbar und votable? – Jaberwocky

+0

Sie können abstrakte Klassen wie oben haben, zum Beispiel: VotableMixin, CommentableMixin. Dann: Klasse Foto (VotableMixin, CommentableMixin) – ziiiro

+0

@ziiro hast du noch eine gute Lernhilfe dafür? – Jaberwocky