2015-11-17 3 views
1

Я делаю свой первый проект Django, который не является учебным пособием, и я подумал, что это хороший учебный опыт, чтобы попытаться создать сайт, похожий на reddit. Поэтому у меня есть модель Link и модель комментариев. Модель Comment имеет GenericForeignKey, потому что она может ссылаться либо на ссылку, либо на другой комментарий. Я хотел бы, чтобы комментарии могли быть связаны друг с другом, но я не понимаю, как это сделать. У кого-нибудь есть идеи?Как вложить модели с помощью общих внешних ключей в Django?

This is the project и вот models.py:

from django.db import models 
from django.utils import timezone 
from django.contrib.contenttypes.fields import GenericForeignKey 
from django.contrib.contenttypes.models import ContentType 

# Create your models here. 
class Link(models.Model): 
    title = models.CharField(max_length=140) 
    url = models.URLField(unique=True) 
    posted = models.DateTimeField(default=timezone.now) 
    upvotes = models.IntegerField(default=0) 
    downvotes = models.IntegerField(default=0) 

    def score(self): 
     return self.upvotes - self.downvotes 

    def __str__(self): 
     return self.title 

class Comment(models.Model): 
    text = models.TextField() 
    posted = models.DateTimeField(default=timezone.now) 
    upvotes = models.IntegerField(default=0) 
    downvotes = models.IntegerField(default=0) 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

    def score(self): 
     return self.upvotes - self.downvotes 

редактировать: Я написал this test и она проходит, что приводит меня к мысли, что комментарии могут фактически гнездо. Вопрос в том, как сделать их гнездом в представлении? Мой вид файла выглядит следующим образом:

from django.shortcuts import render, get_object_or_404 
from django.http import HttpResponseRedirect 
from django.contrib.auth.decorators import login_required 
from django.contrib.contenttypes.models import ContentType 

from .models import Link, Comment 
from .forms import LinkForm, CommentForm 

# Create your views here. 
def links(request): 
    links = Link.objects.all().order_by('-posted') 
    if request.method == 'POST': 
     if request.user.is_authenticated(): 
      form = LinkForm(data=request.POST,auto_id=True) 
      if form.is_valid(): 
       form.full_clean() 
       form.save() 
       return HttpResponseRedirect('/') 
     else: 
      return HttpResponseRedirect('/accounts/login/?next=/') 
    else: 
     form = LinkForm(auto_id=True) 
    return render(request, 'posts/links.html', {'links': links, 'form': form}) 

def comments(request, link_id): 
    link = get_object_or_404(Link, pk=link_id) 
    comments = Comment.objects.filter(
     object_id = link.id, 
     content_type=ContentType.objects.get_for_model(link) 
    ).order_by('-posted') 
    if request.method == 'POST': 
     if request.user.is_authenticated(): 
      form = CommentForm(data=request.POST,auto_id=True) 
      if form.is_valid(): 
       form.full_clean() 
       form.save() 
       return reverse('comments', kwargs={'link_id':link.id}) 
     else: 
      return HttpResponseRedirect('/accounts/login/?next=/{0}/'.format(link.id)) 
    else: 
     form = CommentForm(auto_id=True) 
     return render(request, 'posts/comments.html', {'comments': comments, 'link': link, 'form': form}) 

ответ

1

django-mptt Я использую, чтобы справиться с этой проблемой.

Вы можете просто создать внешний ключ для самого комментария, а затем оставить работу отдых в mptt

Вы должны сделать что-то вроде этого:

from mptt.models import TreeForeignKey, MPTTModel 

class Comment(MPTTModel): 
    .... 
    .... 
    parent = TreeForeignKey('self', related_name='children', 
          blank=True, null=True, db_index=True) 

прочитать документы @django-mptt

+0

Спасибо за ответ! Но не будет ли внешний ключ ссылаться на сам комментарий, чтобы отключить комментарий, чтобы иметь ссылку в качестве родителя? Я имею в виду, что это позволит добавить комментарий к другому комментарию, но набор комментариев также должен ссылаться на конкретную ссылку, не так ли? – Flobin

+0

Если вы попытаетесь использовать комментарий как собственный 'GenericForeignKey', это будет плохая реализация IMO. Комментарий должен иметь родительский «Link», если вы хотите заполнить комментарий «gfk», то как вы определяете, какой вложенный комментарий для какого сообщения? Что я сделаю, просто добавьте 'foreignkey' в' Link' и дайте комментариям иметь комментарии как «Link», так и «parent», поэтому я могу просто вызвать «комментарии по этой ссылке», а затем позволить 'mptt' делать комментарий для меня. – v1k45

+0

Спасибо! Это технически, возможно, не отвечало на мой вопрос, но это помогло решить мою проблему! – Flobin

Смежные вопросы