如何在创建新实例时分配ForeignKey字段

时间:2017-01-19 06:37:53

标签: python django django-models

我正在构建评论系统并尝试实施投票。所以在我创建一个新的Comment对象的行comment = Comment.objects.create(comment_text=ajax_comment, author=str(request.user), destination=id)上,我想添加一个upvotes字段。创建对象时upvotes=0。我该怎么做?

models.py

class Comment(models.Model):
    user = models.ForeignKey(User, default=1)
    destination = models.CharField(default='1', max_length=12, blank=True)
    author = models.CharField(max_length=120, blank=True)
    comment_id = models.IntegerField(default=1)
    parent_id = models.IntegerField(default=0)
    comment_text = models.TextField(max_length=350, blank=True)
    timestamp = models.DateTimeField(default=timezone.now, blank=True)

    def __str__(self):
        return self.comment_text


class CommentScore(models.Model):
    user = models.ForeignKey(User, default=1)
    comment = models.ForeignKey(Comment, related_name='score')
    upvotes = models.IntegerField(default=0)
    downvotes = models.IntegerField(default=0)

    def __str__(self):
        return str(self.comment)

views.py

comment_list = Comment.objects.filter(destination=id)
score = CommentScore.objects.all()

if request.is_ajax():
    if comment.is_valid():
        comment = Comment.objects.create(comment_text=ajax_comment, author=str(request.user), destination=id)
        print(comment)
        comment.save()
        username = str(request.user)
        return JsonResponse({'text': ajax_comment, 'text_length': comment_length, 'username': username})
    else:
        print(comment.errors)

context = {
    'score': score,
    'comment_list': comment_list,
}

return render(request, 'article.html', context)

2 个答案:

答案 0 :(得分:2)

您要做的主要是创建一个新的CommentScore对象,然后将其映射到您的Comment。这可以这样实现。

comment_list = Comment.objects.filter(destination=id)
score = CommentScore.objects.all()

if request.is_ajax():
    if comment.is_valid():
        comment = Comment.objects.create(comment_text=ajax_comment, author=str(request.user), destination=id)
        print(comment)
        comment.save()
        # This line creates a CommentScore model which maps to your Comment model
        com_score = CommentScore.objects.create(comment=comment)
        com_score.save()
        username = str(request.user)
        return JsonResponse({'text': ajax_comment, 'text_length': comment_length, 'username': username})
    else:
        print(comment.errors)

context = {
    'score': score,
    'comment_list': comment_list,
}

return render(request, 'article.html', context)

答案 1 :(得分:2)

在已创建评论对象后,将发生“向上投票”和“向下投票”。因此,一旦发表评论,然后另一个用户访问该对象并选择向上投票或向下投票,您的前端必须使用Comment对象的键调用后端来创建CommentScore对象。基本上会发生这样的事情:

Comment (object) <- CommentScore (object) 
              ^- CommentScore (object)

您将有许多CommentScore对象链接到Comment对象。每个CommentScore对象将记录哪个用户是upvoted(upvote = 1,downvote = 0)或downvoted(upvote = 0,downvote = 1)。 这个设置可以很容易地查询并获得链接到Comment对象的所有CommentScore对象的upvotes或downvotes的总和。

以下是Django文档(https://docs.djangoproject.com/en/1.10/topics/db/examples/many_to_one/)中的一个示例:

在您的情况下,Reporter是评论,文章是CommentScore。

创建一些记者:

  

r = Reporter(first_name='John', last_name='Smith', email='john@example.com')

     

r.save()

     

r2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com')

     

r2.save()

创建文章:

  

从日期时间导入日期

     

a = Article(id=None, headline="This is a test", pub_date=date(2005, 7, 27), reporter=r)

     

a.save()

     

a.reporter.id

     

1

     

a.reporter

     

<Reporter: John Smith>

在这个例子中,您可以获得记者撰写的所有文章:

  

Article.objects.filter(reporter__first_name='John')

     

<QuerySet [<Article: John's second story>, <Article: This is a test>]>

以下是针对您案例的更具体示例:

>>>  from testapp.models import Comment, CommentScore

# Creates one Comment object with pk=1
>>>  Comment.objects.create() 
<Comment: >

# Create 3 ComentScore objects that are associated with the first Comment I create
 CommentScore.objects.create(comment=Comment.objects.get(pk=1))
<CommentScore: >

>>>  CommentScore.objects.create(comment=Comment.objects.get(pk=1))
<CommentScore: >

>>>  CommentScore.objects.create(comment=Comment.objects.get(pk=1))
<CommentScore: >

# Now get the original Comment object that I created in my first step
>>>  cob = Comment.objects.get(pk=1)
>>>  cob.score
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x107d67320>

# Grab all the CommentScore objects associated to that comment
 cob.score.all()
<QuerySet [<CommentScore: >, <CommentScore: >, <CommentScore: >]>

# Print upvote for each CommentScore object that's associated to that Comment I created
>>>  for ob in cob.score.all():
...      print(ob.upvotes)
...  
0
0
0