Я делаю свой первый проект 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})
Спасибо за ответ! Но не будет ли внешний ключ ссылаться на сам комментарий, чтобы отключить комментарий, чтобы иметь ссылку в качестве родителя? Я имею в виду, что это позволит добавить комментарий к другому комментарию, но набор комментариев также должен ссылаться на конкретную ссылку, не так ли? – Flobin
Если вы попытаетесь использовать комментарий как собственный 'GenericForeignKey', это будет плохая реализация IMO. Комментарий должен иметь родительский «Link», если вы хотите заполнить комментарий «gfk», то как вы определяете, какой вложенный комментарий для какого сообщения? Что я сделаю, просто добавьте 'foreignkey' в' Link' и дайте комментариям иметь комментарии как «Link», так и «parent», поэтому я могу просто вызвать «комментарии по этой ссылке», а затем позволить 'mptt' делать комментарий для меня. – v1k45
Спасибо! Это технически, возможно, не отвечало на мой вопрос, но это помогло решить мою проблему! – Flobin