Django:将当前用户指定为评论模型的外键

时间:2016-02-03 09:52:00

标签: python django django-models django-forms

我一直在完成DjangoGirls教程,并尝试改进有关向应用添加评论的部分 - TutorialExtensions

我已将评论添加到一个简单的照片博客应用程序中,但我尝试做的是将author = models.CharField(max_length=200)替换为存储当前/登录用户的替代方案,该用户正在评论照片实例和然后允许我在photo_detail模板上显示。

我以为我接近使用author = models.ForeignKey(User, related_name='Commenter'),但这是错误的:

NOT NULL constraint failed: timeline_comment.author_id

这是我的models.py,包括Photo模型和评论模型:

class Photo(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1)
    title = models.CharField(max_length=120)
    slug = models.SlugField(unique=True)
    image = ProcessedImageField(upload_to=upload_location, 
        null=True, 
        blank=False,
        processors=[Transpose(), ResizeToFit(1000, 1000, False)],
        format='JPEG',
        options={'quality': 50},
        width_field="width_field",
        height_field="height_field")
    height_field = models.IntegerField(default=0)
    width_field = models.IntegerField(default=0)
    description = models.TextField(max_length=1000)
    updated = models.DateTimeField(auto_now=True, auto_now_add=False)
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)

class Comment(models.Model):
    post = models.ForeignKey('timeline.Photo', related_name='comments')
    author = models.CharField(max_length=200)
    text = models.TextField(max_length=1000)
    created_date = models.DateTimeField(default=timezone.now)

相关观点:

def photo_detail(request, slug=None):
    if not request.user.is_authenticated():
        return HttpResponseRedirect("/accounts/login")

    instance = get_object_or_404(Photo, slug=slug)

    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = instance
            comment.save()
            return redirect('timeline:detail', slug=instance.slug)
    else:
        form = CommentForm()

    share_string = quote_plus(instance.description)

    context = {
        "title": instance.title,
        "instance": instance,
        "share_string": share_string,
        "form": form,
    }

    return render(request, "photo_detail.html", context)   

我的forms.py:

class CommentForm(forms.ModelForm):
    text = forms.CharField(widget=forms.Textarea, label='Leave a comment: ')
    class Meta:
        model = Comment
        fields = [
            "text",
        ]

最后是photo_detail视图的模板:

<div class="row">
    <div class="col-md-12" id="comments">
        <p>
            {% if instance.comments.count == 0 %}
            No Comments
            {% elif instance.comments.count == 1 %}
            {{ instance.comments.count }} Comment
            {% else %}
            {{ instance.comments.count }} Comments
            {% endif %}
        </p>
        <hr style="margin-top: 10px;">
            {% for comment in instance.comments.all %}
                <div class="comment">
                    <div class="date pull-right">{{ comment.created_date | timesince }} Ago</div>
                    <strong>{{ comment.author }}</strong>
                    <p>{{ comment.text|linebreaks }}</p>
                </div>
                <hr>
            {% empty %}
                <p>No comments here yet :(</p>
            {% endfor %}
    </div>
</div>

{% if user.is_superuser or user.is_authenticated %} 
<div class="row">
    <div class="col-md-12">
        <form method="POST" class="comment-form" action=''>
            {% csrf_token %}
            {{ form | crispy }}
            <button type="submit" class="comment-add btn btn-lg btn-purple">Add</button>
        </form>
    </div>
</div>
{% endif %}

有人可以为此推荐最佳方法吗?任何帮助将非常感谢!谢谢。

1 个答案:

答案 0 :(得分:3)

使用ForeignKey是正确的[1] - 缺少的部分是您需要在视图中指定它。 comment = form.save(commit=False)之后只需添加一行:

comment.author = request.user

它会起作用。

[1]虽然您不希望related_name为“评论者”(因为它指的是您从用户访问评论的方式:默认为comment_set这更有意义)