django restframework中的Keyerror

hvvq6cgz  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(134)

Views.py

class EventCalenderEventListView(ListAPIView):
    permission_classes=[AllowAny,]
    serializer_class = serializer.EventCalenderSerializer
    def get_queryset(self, *args, **kwargs):
        data = json.loads(self.request.GET.get('filter'))
        category = data.get('category')
        query_list = Event.objects.all().values('start_date').distinct()
        date_list = []
        for i in query_list:
            for key, value in i.items():
                date_list.append(datetime.datetime.strftime(value,'%Y-%m-%d'))
        datas = []
        result = {}
        for dates in date_list:
            result[dates]= []
            query = Event.objects.filter(start_date=dates).order_by('start_date')
            for i in query:
                result[dates].append(i)
            datas.append(result)
            result = {}
        return datas

模型.py

class Event(BaseFields):
    name = models.CharField(max_length=250)
    category = models.ForeignKey(EventCategory,on_delete=models.CASCADE,null=True,blank=True)
    other_event_category = models.CharField(max_length=250,null=True,blank=True)
    meeting_link = models.CharField(max_length=250,null=True,blank=True)
    description = models.TextField(null=True,blank=True)
    start_date = models.DateField(null=True,blank=True)
    end_date = models.DateField(null=True,blank=True)

serializer.py

class EventCalenderSerializer(ModelSerializer):
    category = SerializerMethodField()
    status = SerializerMethodField()
    class Meta:
        model = Event
        fields = fields=('id','name','category','start_date','end_date','status')
    def get_category(self, obj):
        category = {}
        if obj.category:
            category['id'] = obj.category.id
            category['name'] = obj.category.name
            return category
        else:
            category = ""
            return category
    def get_status(self,obj):
        current_date =  datetime.strftime(datetime.today(),'%Y-%m-%d')
        start_date = datetime.strftime(obj.start_date,'%Y-%m-%d')
        if obj.end_date is not None:
            end_date = datetime.strftime(obj.end_date,'%Y-%m-%d')
            if start_date == end_date and start_date < current_date:
                return "completed"
            elif start_date < current_date and end_date < current_date:
                return "completed"
            elif start_date < current_date and end_date > current_date:
                return "progress"
            elif start_date == current_date:
                return "progress"
            else:
                return "upcoming"
        else:
            if start_date < current_date:
                return "completed"
            elif start_date == current_date:
                return "progress"
            else:
                return "upcomng"

预期输出:

[
  {
    "2023-06-01": [
      {
        "name": "event 1",
        "start_date": "2023-06-01",
        "end_date": "2023-06-07"
      }
    ]
  },
  {
    "2023-06-01": [
      {
        "name": "event 2",
        "start_date": "2023-06-01",
        "end_date": "2023-06-07"
      },
      {
        "name": "event 3",
        "start_date": "2023-06-01",
        "end_date": "2023-06-07"
      }
    ]
  }
  ...
]
4si2a6ki

4si2a6ki1#

.get_queryset的响应是传递给.list方法的内容,该方法将序列化并返回准备显示的数据。目前,您正在将其变形为与您的serializer不对应的内容:

[
    {'2023-06-01': 
        [
            <Event: Event object (1)>, 
            <Event: Event object (2)>, 
            <Event: Event object (3)>
        ]
    }
]

此外,这与您在问题中发布的结构(如预期输出)不同,我将假设您使用代码构建的是正确的。
所以,基本上你需要做的就是序列化键值中的事件列表。我们可以通过覆盖.list方法来解决这个问题。然后,遍历你的 “QuerySet”(实际上是一个Array的字典,其中包含一个带有Event对象列表的键),以这种方式序列化这个列表并重新创建你的响应:
views.py

class EventCalenderEventListView(ListAPIView):
    ...

    def get_queryset(self, *args, **kwargs):
        ...

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        data = []
        for event_date in queryset:
            for key, value in event_date.items():
                serializer = self.get_serializer(value, many=True)
                data.append({key: serializer.data})
        return Response(data)

可选

我建议你通过使用QuerySet API提供的方法来清理你的视图,并以不同的方式组织你的数据,这样我们就可以直接用Wrapper序列化数据:
serializers.py

class EventCalenderSerializer(ModelSerializer):
    ...

class Wrapper(serializers.Serializer):
    day = serializers.DateField()
    events = EventCalenderSerializer(many=True)

views.py

class EventCalenderEventListView(ListAPIView):
    permission_classes = [
        AllowAny,
    ]
    serializer_class = Wrapper

    def get_queryset(self, *args, **kwargs):
        # We can go arround the param
        filter_param = self.request.GET.get("filter") or None
        if filter_param:
            filter_param_data = json.loads(filter_param)
            category = filter_param_data.get("category")

        data = []
        date_list = (
            Event.objects.all()
            .values_list("start_date", flat=True)
            .distinct()
        )

        for date in date_list:
            event_list = Event.objects.filter(start_date=date)
            data.append({"day": date, "events": event_list})

        return data

最后,一个基于EventCalenderSerializer的响应示例。如果您想要的字段与问题中预期的字段相同,则从原始序列化程序中删除相应的字段(这对以前的解决方案也有效)。

[
  {
      "day": "2023-06-01",
      "events": [
          {
              "id": 1,
              "name": "Event 1",
              "category": {
                  "id": 1,
                  "name": "some category"
              },
              "start_date": "2023-06-01",
              "end_date": "2023-06-07",
              "status": "completed"
          },
          {
              "id": 2,
              "name": "Event 2",
              "category": {
                  "id": 1,
                  "name": "some category"
              },
              "start_date": "2023-06-01",
              "end_date": "2023-06-07",
              "status": "completed"
          },
          {
              "id": 3,
              "name": "Event 3",
              "category": {
                  "id": 1,
                  "name": "some category"
              },
              "start_date": "2023-06-01",
              "end_date": "2023-06-07",
              "status": "completed"
          }
      ]
  }
]

相关问题