Django REST框架查询集对象没有属性pk

bxgwgixi  于 2023-03-04  发布在  Go
关注(0)|答案(4)|浏览(155)

我正在构建一个更大的基于Django的Web应用程序,但是我遇到了一个API视图的阻塞问题,该视图应该返回一些数据。
在应用程序中,我有一个模型(mail.models.Message)和一个匹配的序列化程序和视图集。
对于报告功能,我需要得到过滤后的结果集,并因此创建了一个单独的rest_framework. views. APIView用于报告。模型位于一个应用程序中,报告位于另一个应用程序中。
以下是模型:

class Message(models.Model):
class Meta:
    ordering = ('-timestamp',)
    get_latest_by = 'timestamp'

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    from_address = models.CharField("From", max_length=511, blank=True, default="", db_index=True)
    from_domain = models.CharField(max_length=255, blank=True, default="", db_index=True)
    to_address = models.CharField("To", max_length=511, blank=True, default="", db_index=True)
    to_domain = models.CharField(max_length=255, blank=True, default="", db_index=True)
    subject = models.TextField(blank=True, default="", db_index=True)
    client_ip = models.GenericIPAddressField("Client IP", db_index=True, null=True)
    mailscanner_hostname = models.CharField(max_length=255, db_index=True)
    spam_score = models.DecimalField(db_index=True, default=0.00, max_digits=7, decimal_places=2)
    mcp_score = models.DecimalField(db_index=True, default=0.00, max_digits=7, decimal_places=2)
    timestamp = models.DateTimeField(db_index=True)
    size = models.FloatField(default=0)
    token = models.CharField(max_length=255, null=True)
    mailq_id = models.TextField("Mailqueue identification", null=True)
    whitelisted = models.BooleanField(db_index=True, default=False)
    blacklisted = models.BooleanField(db_index=True, default=False)
    is_spam = models.BooleanField(db_index=True, default=False)
    is_mcp = models.BooleanField(db_index=True, default=False)
    is_rbl_listed = models.BooleanField("Is RBL listed", db_index=True, default=False)
    quarantined = models.BooleanField(db_index=True, default=False)
    infected = models.BooleanField(db_index=True, default=False)
    released = models.BooleanField(db_index=True, default=False)

    def __str__(self):
        return str(self.id) + "[" + str(self.from_address) + " to " + str(self.to_address) + "]"

以及匹配的串行化器:

class MessageSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Message
        fields = (
            'id',
            'url',
            'from_address',
            'from_domain',
            'to_address',
            'to_domain',
            'subject',
            'client_ip',
            'mailscanner_hostname',
            'spam_score',
            'timestamp',
            'size',
            'token',
            'whitelisted',
            'blacklisted',
            'is_spam',
            'is_rbl_listed',
            'quarantined',
            'infected'
        )

模型上有很多索引来提高搜索和过滤的性能,但是我已经排除了这些索引。
为了进行报告,我创建了这个特殊视图:

class MessageListApiView(ReportApiView):
    serializer_class = MessageSerializer
    queryset = Message.objects.all()

    def get_queryset(self):
        if self.request.method == 'POST':
            filters = self.request.data
            return MessageQuerySetFilter.filter(MessageQuerySetFilter, self.queryset, filters)
        else:
            return self.queryset

    def post(self, request, format=None):
        filters = request.data
        qs = self.get_queryset()
        serializer = MessageSerializer(qs, context={'request': request})
        return Response(serializer.data, 200)

get_queryset中,我使用了一个特殊的类,该类的唯一目的是对查询集应用适当的过滤并返回它。通过一些测试,我发现当我必须返回Response时会出现这个问题。
我得到这个回溯:

Internal Server Error: /api/reports/messages/
Traceback (most recent call last):
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
response = get_response(request)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
response = self.process_exception_by_middleware(e, request)
      File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/django/views/generic/base.py", line 69, in view
return self.dispatch(request, *args, **kwargs)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/rest_framework/views.py", line 494, in dispatch
response = self.handle_exception(exc)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/rest_framework/views.py", line 454, in handle_exception
self.raise_uncaught_exception(exc)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/rest_framework/views.py", line 491, in dispatch
response = handler(request, *args, **kwargs)
  File "/Users/kenneth/Code/mailware/src/reports/views.py", line 44, in post
return Response(serializer.data, 200)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/rest_framework/serializers.py", line 537, in data
ret = super(Serializer, self).data
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/rest_framework/serializers.py", line 262, in data
self._data = self.to_representation(self.instance)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/rest_framework/serializers.py", line 504, in to_representation
ret[field.field_name] = field.to_representation(attribute)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/rest_framework/relations.py", line 376, in to_representation
url = self.get_url(value, self.view_name, request, format)
  File "/Users/kenneth/Code/mailware/lib/python3.6/site-packages/rest_framework/relations.py", line 312, in get_url
lookup_value = getattr(obj, self.lookup_field)
AttributeError: 'QuerySet' object has no attribute 'pk'
[19/Jan/2018 20:05:24] "POST /api/reports/messages/ HTTP/1.1" 500 16389

上面的APIView类继承了一个自定义基类,这个基类继承了rest_framework.views.APIView类,这个类叫做ReportApiView,简单的设置了paginator_classpermission_class

class ReportApiView(APIView):
    permission_classes = (IsAuthenticated,)
    pagination_class = PageNumberPaginationWithPageCount

MessageListApiViewpost方法中,return行似乎出错了,但我找不到它不工作的原因

kyks70gy

kyks70gy1#

您需要将many=True添加到序列化程序查询集:

serializer = MessageSerializer(qs, many=True, context={'request': request})
vjhs03f7

vjhs03f72#

您只需在序列化器中添加many = true serializer = userSerializer.UserSeria(用户,数据=请求.数据,many=True)

wbgh16ku

wbgh16ku3#

我有这个错误,对于那些来自谷歌这里,我的问题是这一个:
我想要序列化的模型有一个包含unique=True的字段。我发送到Serializer的多个数据(使用many=True)不是唯一的(已经在db中),并且不是有一个错误告诉我这一点,而是抛出了"'QuerySet' object has no attribute 'pk'",这真的很混乱。无论如何,在摆脱了唯一性之后,我的代码工作了。

wsewodh2

wsewodh24#

您是否使用了嵌套序列化程序,并且父序列化程序的模型具有unique_together constraint? See below on how to overriding the get_unique_together_validators '方法来禁用唯一在一起检查,因为示例未传递到嵌套序列化程序,因此检查失败

class FooSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = models.Foo
        fields = '__all__'
        list_serializer_class = FooListSerializer

    def get_unique_together_validators(self):
        """Overriding method to disable unique together checks, because the instance is not passed into nested serializer, and hence fails the check"""
        return []

相关问题