我正在尝试使用django rest框架进行嵌套注释功能。 我正在使用Django 2.2和其他框架版本3.10.2,但是在这里,我正在使用Django 1.9的youtube中观看视频。 无论我在URL中传递了什么值,它总是返回验证错误,指出 model_qs为空。 我无法解决此问题。有人可以调查一下吗 让我指出我在这里做错了。
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
urls.py
urlpatterns = [
path('create/', CommentCreateAPIView.as_view(), name='create'),
]
model.py
class CommentManager(models.Manager):
def all(self):
qs = super(CommentManager, self).filter(parent=None)
return qs
def filter_by_instance(self, instance):
content_type = ContentType.objects.get_for_model(instance.__class__)
obj_id = instance.id
qs = super(CommentManager, self).filter(content_type=content_type, object_id=obj_id).filter(parent=None)
return qs
def create_by_model_type(self, model_type, slug, content, user, parent_obj=None):
model_qs = ContentType.objects.filter(model=model_type)
if model_qs.exists():
some_model = model_qs.first().model_class()
obj_qs = some_model.objects.filter(slug=slug)
if obj_qs.exists() and obj_qs.count() == 1:
instance = self.model()
instance.content = content
instance.user = user
instance.content_type = model_qs.first()
instance.object_id = obj_qs.first().id
if parent_obj:
instance.parent = parent_obj
instance.save()
return instance
return None
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)
content = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
objects = CommentManager()
class Meta:
ordering = ['-timestamp']
def __unicode__(self):
return str(self.user.username)
def __str__(self):
return str(self.user.username)
def get_absolute_url(self):
return reverse("comments:thread", kwargs={"id": self.id})
def get_delete_url(self):
return reverse("comments:delete", kwargs={"id": self.id})
def children(self): # Replies
return Comment.objects.filter(parent=self)
@property
def is_parent(self):
if self.parent is not None:
return False
return True
serializers.py
def create_comment_serializer(model_type='post', slug=None, parent_id=None, user=None):
class CommentCreateSerializer(ModelSerializer):
class Meta:
model = Comment
fields = [
'id',
'parent',
'content',
'timestamp',
]
def __init__(self, *args, **kwargs):
self.model_type = model_type
self.slug = slug
self.parent_obj = None
if parent_id:
parent_qs = Comment.objects.filter(id=parent_id)
if parent_qs.exists() and parent_qs.count() == 1:
self.parent_obj = parent_qs.first()
return super(CommentCreateSerializer, self).__init__(*args, **kwargs)
def validate(self, data):
model_type = self.model_type
model_qs = ContentType.objects.filter(model=model_type)
print(model_qs) # This always return <QuerySet []>
if not model_qs.exists() or model_qs.count() != 1:
raise ValidationError("This is not a valid content types")
some_model = model_qs.first().model_class()
obj_qs = some_model.objects.filter(slug=self.slug)
if not obj_qs.exists() or obj_qs.count() != 1:
raise ValidationError("This is not a valid slug")
return data
def create(self, validated_data):
content = validated_data.get("content")
if user:
main_user = user
else:
main_user = User.objects.all().first()
model_type = self.model_type
slug = self.slug
parent_obj = self.parent_obj
comment = Comment.objects.create_by_model_type(model_type, slug, content, main_user, parent_obj=parent_obj,)
return comment
return CommentCreateSerializer
views.py
class CommentCreateAPIView(CreateAPIView):
queryset = Comment.objects.all()
# permission_classes = [IsAuthenticated]
def get_serializer_class(self):
model_type = self.request.GET.get("type")
slug = self.request.GET.get("slug")
parent_id = self.request.GET.get("parent_id", None)
return create_comment_serializer(
model_type=model_type,
slug=slug,
parent_id=parent_id,
user=self.request.user
)