如何从其他表中获取数据,例如序列化程序类django-rest-framework中的左连接

时间:2019-12-13 09:50:16

标签: django serialization django-models django-rest-framework django-views

我有模特

class Event(models.Model):
    main_image = models.ImageField(upload_to='events/images', default="")
    event_name = models.CharField(max_length=100, default="")
    is_active = models.BooleanField(default=True)
    is_approved = models.BooleanField(default=True)
    created_at = models.DateTimeField(default=timezone.now)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)

def __str__(self):
    return self.event_name

另一个是

class Favourite(models.Model):
    event = models.ForeignKey(
    Event, on_delete=models.CASCADE, limit_choices_to={'is_active': True}, related_name="fav_data", 
    related_query_name="fav_data")
    user_token = models.TextField(blank=True)
    is_fav = models.BooleanField(default=True)

这是一个序列化程序类

class FavSerializer(serializers.ModelSerializer):
class Meta:
    model = Favourite
    fields = ['id', 'event', 'user_token', 'is_fav']

其他是

class eventSerializer(serializers.ModelSerializer):
    additional_images = additionalImagesSerializer(many=True, read_only=True)
    fav_data = FavSerializer(many=True,read_only=True)

    class Meta:
        model = Event
        fields = ['id', 'main_image', 'event_name', 'additional_images', 'fav_data']

我的查看方法是

class eventList(ListAPIView):
    serializer_class = eventSerializer
    filter_backends = [DjangoFilterBackend,
                   filters.SearchFilter, filters.OrderingFilter]
    search_fields = ['event_name']
    filterset_fields = ['event_name']
    ordering_fields = '__all__'
    ordering = ['-id']



def get_queryset(self):
    token = self.kwargs['token']
    return Event.objects.all().filter(is_active=1, is_approved=1)

这给出结果

{
"count": 12,
"next": "http://192.168.0.104:8000/event/allEvents/token1/?limit=10&offset=10",
"previous": null,
"results": [
    {
        "id": 16,
        "main_image": "http://192.168.0.104:8000/media/events/images/1569666693-6th-pakistan-mega-leather-show.jpg",
        "event_name": "6th Pakistan Mega leather show",
        "event_tag": [
            5,
            6,
            7
        ],
        "additional_images": [],
        "fav_data": [
            {
                "id": 6,
                "event": 16,
                "user_token": "token1",
                "is_fav": true
            },
            {
                "id": 7,
                "event": 16,
                "user_token": "token2",
                "is_fav": true
            },
            {
                "id": 8,
                "event": 16,
                "user_token": "token3",
                "is_fav": true
            },
            {
                "id": 9,
                "event": 16,
                "user_token": "token4",
                "is_fav": true
            }
        ]
    },
    {
        "id": 15,
        "main_image": "http://192.168.0.104:8000/media/events/images/1573803406-tsx-02.jpeg",
        "event_name": "The Stock Exchange",
        "event_tag": [
            8
        ],
        "additional_images": [],
        "fav_data": [
            {
                "id": 10,
                "event": 15,
                "user_token": "token1",
                "is_fav": true
            },
            {
                "id": 11,
                "event": 15,
                "user_token": "token2",
                "is_fav": true
            }
        ]
    },
 ]
}

问题是它给出结果中的所有fav_data对象,而我只想要fav_data中给出了user_token的那些url。如果在该user_token中存在event,则仅显示相关的fav_data对象,否则显示空的fav_data。 以及令牌如何发送到序列化器方法并调整查询 我想要这样的结果

{
"count": 12,
"next": "http://192.168.0.104:8000/event/allEvents/token1/?limit=10&offset=10",
"previous": null,
"results": [
    {
        "id": 16,
        "main_image": "http://192.168.0.104:8000/media/events/images/1569666693-6th-pakistan-mega-leather-show.jpg",
        "event_name": "6th Pakistan Mega leather show",
        "event_tag": [
            5,
            6,
            7
        ],
        "additional_images": [],
        "fav_data": [
            {
                "id": 6,
                "event": 16,
                "user_token": "token1",
                "is_fav": true
            },

        ]
    },
    {
        "id": 15,
        "main_image": "http://192.168.0.104:8000/media/events/images/1573803406-tsx-02.jpeg",
        "event_name": "The Stock Exchange",
        "event_tag": [
            8
        ],
        "additional_images": [],
        "fav_data": [
            {
                "id": 10,
                "event": 15,
                "user_token": "token1",
                "is_fav": true
            },
        ]
    },
    {
        "id": 14,
        "main_image": "http://192.168.0.104:8000/media/events/images/1573803406-tsx-02.jpeg",
        "event_name": "The Stock Exchange",
        "event_tag": [
            8
        ],
        "additional_images": [],
        "fav_data": []
    },
   ]
  }

1 个答案:

答案 0 :(得分:3)

您可以在序列化程序上下文中传递user_token

views.py

class eventList(ListAPIView):
    ...


    def get_serializer_context(self):
        context = super(eventList, self).get_serializer_context()

        context['user_token'] = self.kwargs.get('token')
        return context

serializer.py

class EventSerializer(serializers.ModelSerializer):
    ...
    fav_data = serializers.SerializerMethodField()

    def get_fav_data(self, obj):
        favourites = Favourite.objects.filter(event=obj, user_token=self.context.get('user_token'))
        return FavSerializer(favourites , many=True).data