@ -0,0 +1,26 @@ |
||||
# Generated by Django 4.1.1 on 2022-09-23 22:51 |
||||
|
||||
from django.db import migrations, models |
||||
import django.db.models.deletion |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('article', '0005_rename_tag_article_tags'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='Avatar', |
||||
fields=[ |
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('content', models.ImageField(upload_to='avatar/%Y%m%d')), |
||||
], |
||||
), |
||||
migrations.AddField( |
||||
model_name='article', |
||||
name='avatar', |
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='articles', to='article.avatar'), |
||||
), |
||||
] |
@ -0,0 +1,19 @@ |
||||
# Generated by Django 4.1.1 on 2022-09-23 23:57 |
||||
|
||||
from django.db import migrations, models |
||||
import django.db.models.deletion |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('article', '0006_avatar_article_avatar'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='article', |
||||
name='avatar', |
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='article', to='article.avatar'), |
||||
), |
||||
] |
@ -0,0 +1,3 @@ |
||||
from django.contrib import admin |
||||
|
||||
# Register your models here. |
@ -0,0 +1,6 @@ |
||||
from django.apps import AppConfig |
||||
|
||||
|
||||
class CommentConfig(AppConfig): |
||||
default_auto_field = 'django.db.models.BigAutoField' |
||||
name = 'comment' |
@ -0,0 +1,32 @@ |
||||
# Generated by Django 4.1.1 on 2022-09-23 23:57 |
||||
|
||||
from django.conf import settings |
||||
from django.db import migrations, models |
||||
import django.db.models.deletion |
||||
import django.utils.timezone |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
initial = True |
||||
|
||||
dependencies = [ |
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
||||
('article', '0007_alter_article_avatar'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.CreateModel( |
||||
name='Comment', |
||||
fields=[ |
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('content', models.TextField()), |
||||
('created', models.DateTimeField(default=django.utils.timezone.now)), |
||||
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='article.article')), |
||||
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to=settings.AUTH_USER_MODEL)), |
||||
], |
||||
options={ |
||||
'ordering': ['-created'], |
||||
}, |
||||
), |
||||
] |
@ -0,0 +1,30 @@ |
||||
from django.db import models |
||||
from django.utils import timezone |
||||
from article.models import Article |
||||
from django.contrib.auth.models import User |
||||
|
||||
|
||||
class Comment(models.Model): |
||||
# 评论人 |
||||
author = models.ForeignKey( |
||||
User, |
||||
on_delete=models.CASCADE, |
||||
related_name='comments', |
||||
) |
||||
# 文章 |
||||
article = models.ForeignKey( |
||||
Article, |
||||
on_delete=models.CASCADE, |
||||
related_name='comments', |
||||
) |
||||
# 评论内容 |
||||
content = models.TextField() |
||||
# 评论时间 |
||||
created = models.DateTimeField(default=timezone.now) |
||||
|
||||
class Meta: |
||||
ordering = ['-created'] |
||||
|
||||
def __str__(self): |
||||
# 展示前20个字符 |
||||
return self.content[:20] |
@ -0,0 +1,26 @@ |
||||
from rest_framework.permissions import BasePermission, SAFE_METHODS |
||||
|
||||
|
||||
class IsOwnerOrReadOnly(BasePermission): |
||||
""" |
||||
只有作者本人可以修改,其他人只能查看 |
||||
""" |
||||
message = "You must be the owner to update" |
||||
|
||||
def safe_methods_or_owner(self, request, func): |
||||
if request.method in SAFE_METHODS: |
||||
return True |
||||
return func() |
||||
|
||||
def has_permission(self, request, view): |
||||
return self.safe_methods_or_owner( |
||||
request, |
||||
lambda: request.user.is_authenticated |
||||
) |
||||
|
||||
def has_object_permission(self, request, view, obj): |
||||
return self.safe_methods_or_owner( |
||||
request, |
||||
lambda: obj.author == request.user # 验证当前评论的作者和当前登录的用户是否为同一个人 |
||||
) |
||||
|
@ -0,0 +1,15 @@ |
||||
from rest_framework import serializers |
||||
from user_info.serializers import UserDescSerializer |
||||
from comment.models import Comment |
||||
|
||||
|
||||
class CommentSerializer(serializers.ModelSerializer): |
||||
"""评论的序列化器""" |
||||
url = serializers.HyperlinkedIdentityField(view_name='comment-detail') |
||||
author = UserDescSerializer(read_only=True) |
||||
|
||||
class Meta: |
||||
model = Comment |
||||
fields = '__all__' |
||||
extra_kwargs = {'created': {'read_only': True}} |
||||
|
@ -0,0 +1,3 @@ |
||||
from django.test import TestCase |
||||
|
||||
# Create your tests here. |
@ -0,0 +1,14 @@ |
||||
from rest_framework import viewsets |
||||
|
||||
from comment.models import Comment |
||||
from comment.serializers import CommentSerializer |
||||
from comment.permissions import IsOwnerOrReadOnly |
||||
|
||||
|
||||
class CommentViewSet(viewsets.ModelViewSet): |
||||
queryset = Comment.objects.all() |
||||
serializer_class = CommentSerializer |
||||
permission_classes = [IsOwnerOrReadOnly] |
||||
|
||||
def perform_create(self, serializer): |
||||
serializer.save(author=self.request.user) |
After Width: | Height: | Size: 1006 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 943 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.2 KiB |