代码改变世界

119-用django实现评论功能

2020-08-11 23:48  lzhshn  阅读(575)  评论(0编辑  收藏  举报

要实现的功能其实是一系列的,比如对评论进行评论,比如可以点赞,但是这些都要依赖注册-登录功能实现之后,这里先实现简单的评论。

django可以用第三方的模块来直接实现评论(注释)功能,不过个人看了一下,比较复杂,而且貌似文档维护的挺差,所以这里直接手写一个评论功能。想了解第三方模块直接实现评价功能的,移步到:https://pypi.org/project/django-contrib-comments/

 

评价和日记是多对一的关系,即一篇日记下面,可以有多个评价。所以这里需要使用两个模型,然后让他们互相关联。

 

from django.db import models
from taggit.managers import TaggableManager
from ckeditor.fields import RichTextField


# Create your models here.
class MyNote(models.Model):
    title = models.CharField(max_length=64, default='a default title')
    content = RichTextField(config_name='awesome_ckeditor')
    pub_time = models.DateTimeField()
    update_time = models.DateTimeField(auto_now=True)
    pub_date = models.DateField(auto_now=True)
    personal_tags = TaggableManager()

    def __str__(self):
        return self.title[0:32]


class Comment(models.Model):
    relation_note = models.ForeignKey('MyNote', on_delete=models.CASCADE)
    add_time = models.DateTimeField(auto_now=True)
    content = models.TextField()

    def __str__(self):
        return self.content[0:32]

  

  

note模型和comment模型,分别定义,然后利用一个字段:relation_note,以及models.ForeignKey方法来实现关联。其他示例中,这里字段可能通常是mynote,其实可以设置任何名称,比如:relation_note,不一定非要是那个多对一关系中的“一“的小写。

relation_note是什么?是所指向的那个关联对象的返回值,即:

    def __str__(self):
        return self.title[0:32]

  

另外使用了一个TextField,这里表示用一个简易的多行(可拖动)的文本输入框。

 

接下来是views和templates里的内容:

def one_note(request, pk):
    pk_note = MyNote.objects.get(id=pk)
    all_comment = pk_note.comment_set.all()
    context = {'pk_note': pk_note, 'date_index': list(set(date_list)),
               'tag_index': list(set(tag_list)), 'all_comment': all_comment}
    return render(request, 'one_note.html', context)

  

上面这个函数,首先通过url传入的pk值,获得具体某篇日记,然后获取所有的评论:all_comment = pk_note.comment_set.all()

其中,comment_set,是的django自动产生的一个关联描述字段,他表示:可以通过note来获取所有关联的comment,格式为:那个关联的模型的小写加上_set。当一个模型class下,有多个属性都要关联到同一个模型时,需要使用related_name=来显式地指定。比如related_name=‘com_and_note‘,则pk_note.comment_set.all()可以用pk_note.com_and_note.all()代替。

 

再看模板里怎么写

 

<body>


    {% block content %}
    <div class="left">
        <div>
            <h3>{{pk_note.title}}</h3>
            <p>Create time:{{pk_note.pub_time}} Update time:{{pk_note.update_time}}</p>
            {% autoescape off %}
            <p>{{pk_note.content}}</p>
            {% endautoescape %}
            <p>{{pk_note.personal_tags.all}}</p>
        </div>
        <div id="comment">
            <h4>comment</h4>
            {% for comment in all_comment %}
                <p>{{comment.add_time}}</p>
                <p>{{comment.content}}</p>
                <p>{{comment.relation_note}}</p>
            {% endfor %}
        </div>
    </div>
    {% endblock %}



</body>

  

 

当找到所有评论个,利用for循环,逐个取出来显示即可。

注意最后使用了这样一个变量:<p>{{comment.relation_note}}</p>,如果你看到这个示例,你可以在你的工程里打开,看看它输出了什么。