繁体   English   中英

一对多关系中的查询集

[英]Queryset in one to many relation

我正在尝试获取具有相关元素的Json元素

我有两张桌子, ServiceRoom 一项服务有许多房间。 我想获得room_id = x的服务。

楷模

class Service(models.Model):
    name = models.CharField(max_length=255, blank=True, null=True)
    class Meta:
        managed = True
        db_table = 'Service'

class Room(models.Model):
    name = models.CharField(max_length=255, blank=True, null=True)
    service = models.ForeignKey(Service, models.DO_NOTHING, blank=True, 
    null=True)
    class Meta:
        managed = True
        db_table = 'Room'

序列化器

class ServiceSerializer(serializers.ModelSerializer):
    room_set = RoomSerializer(many=True, read_only=True)
    class Meta:
       model = Service
       fields = ('name','room_set')
class RoomSerializer(serializers.ModelSerializer):
    class Meta:
        model = Room        
        fields = '__all__'

看法

queryset = Service.objects.filter(room__id=1)
serializer = ServiceSerializer(queryset, many=True)
return JsonResponse(serializer.data, safe=False)

我期待这样的 Json:

{
     "name": "Hotel1",
     "room_set": [
     {
           "id": 1,
           "name": "Room1"
      },

但我明白了:

 {
     "name": "Hotel1",
     "room_set": [
     {
           "id": 1,
           "name": "Room1",
      },
      {
            "id": 2,
            "name": "Room2",
      },
      {
             "id": 3,
             "name": "Room3",
      }
  } 

是否有可能获得像我期望的那样的 json?

您可以通过添加带有过滤查询集的自定义Prefetch对象 [Django-doc]来修补该集合,例如:

from django.db.models import Prefetch

queryset = Service.objects.filter(
    room__id=1
).prefetch_related(
    Prefetch('room_set', queryset=Room.objects.filter(id=1), to_attr='room_set1')
)
serializer = ServiceSerializer(queryset, many=True)
return JsonResponse(serializer.data, safe=False)

并让Serializer解析新的相关管理器:

class ServiceSerializer(serializers.ModelSerializer):
    room_set = RoomSerializer(many=True, read_only=True, source='room_set1')
    class Meta:
       model = Service
       fields = ('name','room_set1')
class RoomSerializer(serializers.ModelSerializer):
    class Meta:
        model = Room        
        fields = '__all__'

您可以通过序列化器上下文传递房间 id 并在SerializerMethodField() 中进行相应的过滤

class ServiceSerializer(serializers.ModelSerializer):
    rooms = serializers.SerializerMethodField()
    class Meta:
       model = Service
       fields = ('name','rooms')

    get_rooms(self,service):
       room_id = self.get_context('room')
       if room_id:
         queryset = service.rooms_set.filter(id=room_id)
         return RoomSerializer(queryset,many=True).data
       return RoomSerializer(service.rooms_set.all(),many=True).data

serializer = ServiceSerializer(queryset, many=True,context={'room':1})
return JsonResponse(serializer.data, safe=False)

这是如何通过序列化程序完成它并且它是高度可定制的, Willem Van Onsem的回答足够简短,但它也需要两个与我相同的查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM