# 模型类
from __future__ import unicode_literals
import uuid
from django.utils.encoding import python_2_unicode_compatible
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.db import models
@python_2_unicode_compatible
class Comment(models.Model):
"""使用Django中的ContentType, 同时关联用户对模型的投票"""
uuid_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
content = models.CharField(max_length=255, verbose_name="评论内容")
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, related_name="commentator", on_delete=models.SET_NULL,
verbose_name='评论者')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
"""多级评论需要 自关联"""
root = models.ForeignKey('self', models.SET_NULL, null=True, blank=True, related_name='root_comment',
verbose_name='根评论')
parent = models.ForeignKey("self", models.SET_NULL, related_name="parent_comment", null=True, blank=True,
verbose_name='上级评论')
reply_to = models.ForeignKey(settings.AUTH_USER_MODEL, models.SET_DEFAULT, default=1, null=True, blank=True,
related_name='replier', verbose_name='被回复者')
content_type = models.ForeignKey(ContentType, related_name='comment_on', on_delete=models.CASCADE)
object_id = models.CharField(max_length=255)
comment = GenericForeignKey() # 等同于GenericForeignKey()
class Meta:
verbose_name = "评论"
verbose_name_plural = verbose_name
ordering = ['-created_at'] # 指明默认排序
# SQL优化
index_together = ('content_type', 'object_id') # 联合唯一索引
def __str__(self):
return self.content
# 获取评论
class CommentDetailView(generics.RetrieveUpdateDestroyAPIView):
serializer_class = CommentsSerializer
permission_classes = (IsAuthenticated,)
queryset = Comment.objects.all()
lookup_field = 'uuid_id'
def build_tree(self, queryset):
for obj in queryset:
data = self.get_serializer(obj).data # 序列化
data['subs'] = self.build_tree(obj.parent_comment.all()) # 反向解析取值
yield data # 细节二:yield
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
data = self.build_tree([instance]) # 细节一:列表传参,方便递归
return Response(data)
网友评论