This commit is contained in:
24
backend/community/migrations/0016_reply_likes_topic_likes.py
Normal file
24
backend/community/migrations/0016_reply_likes_topic_likes.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 6.0.1 on 2026-03-02 12:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('community', '0015_topic_status'),
|
||||
('shop', '0039_vccourse_video_embed_code'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='reply',
|
||||
name='likes',
|
||||
field=models.ManyToManyField(blank=True, related_name='liked_replies', to='shop.wechatuser', verbose_name='点赞用户'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='topic',
|
||||
name='likes',
|
||||
field=models.ManyToManyField(blank=True, related_name='liked_topics', to='shop.wechatuser', verbose_name='点赞用户'),
|
||||
),
|
||||
]
|
||||
@@ -143,6 +143,7 @@ class Topic(models.Model):
|
||||
related_course = models.ForeignKey(VCCourse, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="关联课程")
|
||||
|
||||
view_count = models.IntegerField(default=0, verbose_name="浏览量")
|
||||
likes = models.ManyToManyField(WeChatUser, related_name='liked_topics', blank=True, verbose_name="点赞用户")
|
||||
is_pinned = models.BooleanField(default=False, verbose_name="置顶")
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="发布时间")
|
||||
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
|
||||
@@ -209,6 +210,7 @@ class Reply(models.Model):
|
||||
content = models.TextField(verbose_name="回复内容", help_text="支持Markdown格式")
|
||||
author = models.ForeignKey(WeChatUser, on_delete=models.CASCADE, related_name='replies', verbose_name="回复者")
|
||||
reply_to = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='children', verbose_name="回复楼层")
|
||||
likes = models.ManyToManyField(WeChatUser, related_name='liked_replies', blank=True, verbose_name="点赞用户")
|
||||
is_pinned = models.BooleanField(default=False, verbose_name="置顶")
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="回复时间")
|
||||
|
||||
|
||||
@@ -88,12 +88,23 @@ class ReplySerializer(serializers.ModelSerializer):
|
||||
write_only=True,
|
||||
required=False
|
||||
)
|
||||
like_count = serializers.IntegerField(source='likes.count', read_only=True)
|
||||
is_liked = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Reply
|
||||
fields = ['id', 'topic', 'content', 'author', 'author_info', 'reply_to', 'media', 'created_at', 'media_ids', 'is_pinned']
|
||||
fields = ['id', 'topic', 'content', 'author', 'author_info', 'reply_to', 'media', 'created_at', 'media_ids', 'is_pinned', 'like_count', 'is_liked']
|
||||
read_only_fields = ['author', 'created_at']
|
||||
|
||||
def get_is_liked(self, obj):
|
||||
request = self.context.get('request')
|
||||
if not request:
|
||||
return False
|
||||
user = get_current_wechat_user(request)
|
||||
if user:
|
||||
return obj.likes.filter(id=user.id).exists()
|
||||
return False
|
||||
|
||||
def create(self, validated_data):
|
||||
media_ids = validated_data.pop('media_ids', [])
|
||||
reply = super().create(validated_data)
|
||||
@@ -106,6 +117,8 @@ class TopicSerializer(serializers.ModelSerializer):
|
||||
replies = ReplySerializer(many=True, read_only=True)
|
||||
media = TopicMediaSerializer(many=True, read_only=True)
|
||||
is_verified_owner = serializers.BooleanField(read_only=True)
|
||||
like_count = serializers.IntegerField(source='likes.count', read_only=True)
|
||||
is_liked = serializers.SerializerMethodField()
|
||||
|
||||
product_info = ESP32ConfigSerializer(source='related_product', read_only=True)
|
||||
service_info = ServiceSerializer(source='related_service', read_only=True)
|
||||
@@ -125,10 +138,20 @@ class TopicSerializer(serializers.ModelSerializer):
|
||||
'related_service', 'service_info',
|
||||
'related_course', 'course_info',
|
||||
'view_count', 'is_pinned', 'created_at', 'updated_at',
|
||||
'is_verified_owner', 'replies', 'media', 'media_ids'
|
||||
'is_verified_owner', 'replies', 'media', 'media_ids',
|
||||
'like_count', 'is_liked'
|
||||
]
|
||||
read_only_fields = ['author', 'view_count', 'created_at', 'updated_at', 'is_verified_owner', 'status']
|
||||
|
||||
def get_is_liked(self, obj):
|
||||
request = self.context.get('request')
|
||||
if not request:
|
||||
return False
|
||||
user = get_current_wechat_user(request)
|
||||
if user:
|
||||
return obj.likes.filter(id=user.id).exists()
|
||||
return False
|
||||
|
||||
def create(self, validated_data):
|
||||
media_ids = validated_data.pop('media_ids', [])
|
||||
topic = super().create(validated_data)
|
||||
|
||||
@@ -284,6 +284,22 @@ class TopicViewSet(viewsets.ModelViewSet):
|
||||
return Response({'error': '请先登录'}, status=401)
|
||||
return super().create(request, *args, **kwargs)
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def like(self, request, pk=None):
|
||||
obj = self.get_object()
|
||||
user = get_current_wechat_user(request)
|
||||
if not user:
|
||||
return Response({'error': '请先登录'}, status=401)
|
||||
|
||||
if obj.likes.filter(id=user.id).exists():
|
||||
obj.likes.remove(user)
|
||||
liked = False
|
||||
else:
|
||||
obj.likes.add(user)
|
||||
liked = True
|
||||
|
||||
return Response({'liked': liked, 'count': obj.likes.count()})
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
instance.view_count += 1
|
||||
@@ -310,6 +326,22 @@ class ReplyViewSet(viewsets.ModelViewSet):
|
||||
return Response({'error': '请先登录'}, status=401)
|
||||
return super().create(request, *args, **kwargs)
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def like(self, request, pk=None):
|
||||
obj = self.get_object()
|
||||
user = get_current_wechat_user(request)
|
||||
if not user:
|
||||
return Response({'error': '请先登录'}, status=401)
|
||||
|
||||
if obj.likes.filter(id=user.id).exists():
|
||||
obj.likes.remove(user)
|
||||
liked = False
|
||||
else:
|
||||
obj.likes.add(user)
|
||||
liked = True
|
||||
|
||||
return Response({'liked': liked, 'count': obj.likes.count()})
|
||||
|
||||
import requests
|
||||
|
||||
class TopicMediaViewSet(viewsets.ViewSet):
|
||||
|
||||
Reference in New Issue
Block a user