如何使用 ContentType 的筛选器来检查模型实例是否已存在



我正在尝试基于此实现类似的功能。我想限制用户只点击一次喜欢的事件。但是我收到以下错误。我在底部添加了完整的错误详细信息

Exception Type: AttributeError at /api/event/likes/create/
Exception Value: 'str' object has no attribute '_meta'

models.py

class ThumbsUpManager(models.Manager):
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 Thumbsup(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
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.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=True)
objects = ThumbsUpManager()
class Meta:
ordering = ['-timestamp']

def __str__(self):
return str(self.user.username)

@property
def is_parent(self):
if self.parent is not None:
return False
return True

urls.py

urlpatterns = [
path('create/', ThumbsUpCreateAPIView.as_view(), name='create'),
]

view.py

class ThumbsUpCreateAPIView(CreateAPIView):
queryset = Thumbsup.objects.all()
permission_classes = [IsAuthenticated, ]
def get_serializer_class(self):
model_type = self.request.GET.get("type")
slug = self.request.GET.get("slug")
obj_qs = Thumbsup.objects.all()
print(obj_qs)
parent_id = self.request.GET.get("parent_id", None)
return create_thumbs_up_serializer(
model_type=model_type,
slug=slug,
parent_id=parent_id,
user=self.request.user
)

serializers.py

def create_thumbs_up_serializer(model_type=None, slug=None, parent_id=None, user=None):
class ThumbsUpCreateSerializer(ModelSerializer):
class Meta:
model = Thumbsup
fields = [
'id',
'content',
'timestamp',
]
def __init__(self, *args, **kwargs):
self.model_type = model_type
self.slug = slug
self.parent_obj = None
self.user = user
if parent_id:
parent_qs = Thumbsup.objects.filter(id=parent_id)
if parent_qs.exists() and parent_qs.count() == 1:
self.parent_obj = parent_qs.first()
return super(ThumbsUpCreateSerializer, self).__init__(*args, **kwargs)
def validate(self, data):
model_type = self.model_type
slug = self.slug
model_qs = ContentType.objects.filter(model=model_type)
if not model_qs.exists() or model_qs.count() != 1:
raise ValidationError("This is not a valid content type")
SomeModel = model_qs.first().model_class()
obj_qs = SomeModel.objects.filter(slug=self.slug)
if not obj_qs.exists() or obj_qs.count() != 1:
raise ValidationError("This is not a slug for this content type")
######################### ######################### ######################### 
How do I need to make query here to check if the user already liked the Event or not?
I tried the following way, but it is not working.

user_act = Thumbsup.objects.filter(user=self.user, content_type=ContentType.objects.get_for_model(model_type))
if user_act.exists():
raise ValidationError("You have already liked the event")

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
thumbsup = Thumbsup.objects.create_by_model_type(
model_type, slug, content, main_user,
parent_obj=parent_obj,
)
return thumbsup
return ThumbsUpCreateSerializer

追踪:

File "E:GITblogbackendvenvlibsite-packagesdjangocorehandlersexception.py" in inner
34.             response = get_response(request)
File "E:GITblogbackendvenvlibsite-packagesdjangocorehandlersbase.py" in _get_response
115.                 response = self.process_exception_by_middleware(e, request)
File "E:GITblogbackendvenvlibsite-packagesdjangocorehandlersbase.py" in _get_response
113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "E:GITblogbackendvenvlibsite-packagesdjangoviewsdecoratorscsrf.py" in wrapped_view
54.         return view_func(*args, **kwargs)
File "E:GITblogbackendvenvlibsite-packagesdjangoviewsgenericbase.py" in view
71.             return self.dispatch(request, *args, **kwargs)
File "E:GITblogbackendvenvlibsite-packagesrest_frameworkviews.py" in dispatch
497.             response = self.handle_exception(exc)
File "E:GITblogbackendvenvlibsite-packagesrest_frameworkviews.py" in handle_exception
457.             self.raise_uncaught_exception(exc)
File "E:GITblogbackendvenvlibsite-packagesrest_frameworkviews.py" in raise_uncaught_exception
468.         raise exc
File "E:GITblogbackendvenvlibsite-packagesrest_frameworkviews.py" in dispatch
494.             response = handler(request, *args, **kwargs)
File "E:GITblogbackendvenvlibsite-packagesrest_frameworkgenerics.py" in post
190.         return self.create(request, *args, **kwargs)
File "E:GITblogbackendvenvlibsite-packagesrest_frameworkmixins.py" in create
18.         serializer.is_valid(raise_exception=True)
File "E:GITblogbackendvenvlibsite-packagesrest_frameworkserializers.py" in is_valid
235.                 self._validated_data = self.run_validation(self.initial_data)
File "E:GITblogbackendvenvlibsite-packagesrest_frameworkserializers.py" in run_validation
433.             value = self.validate(value)
File "E:GITtest-heroku4thumbsupapiserializers.py" in validate
124.             user_act = Thumbsup.objects.filter(user=self.user, content_type=ContentType.objects.get_for_model(model_type))
File "E:GITblogbackendvenvlibsite-packagesdjangocontribcontenttypesmodels.py" in get_for_model
40.         opts = self._get_opts(model, for_concrete_model)
File "E:GITblogbackendvenvlibsite-packagesdjangocontribcontenttypesmodels.py" in _get_opts
27.             model = model._meta.concrete_model
Exception Type: AttributeError at /api/event/likes/create/
Exception Value: 'str' object has no attribute '_meta'

我在保存在模型管理器中之前检查了模型实例,如下所示,它工作正常。我不知道这是否是完成任务的正确方法(我对 django 很陌生。非常欢迎提出建议(

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
#### Here I have checked for existence before saving the instance ####
if Thumbsup.objects.filter(object_id=instance.object_id, user=instance.user).exists():
raise ValidationError({'already_liked': 'You have already liked the item'})
instance.save()
return instance
return None

最新更新