如何在查询集中获得一对多的结果

How to get one to many like result in a queryset

如何在查询集中实现一对多结果。

我正在查询 return 的结果与结帐日期相匹配。是否可以修改结果,以便 return 房间阵列在一个 ref_id 下,其中 ref_id 和结账日期匹配?

# models.py
class Booking(models.Model):
    ref_id = models.TextField(null=True)
    room = models.ForeignKey(Room, on_delete=models.SET_NULL, null=True)
    check_in_date = models.DateField(blank=False, null=False)
    check_out_date = models.DateField(blank=False, null=False)

# serializer.py
class RoomSerializer(serializers.ModelSerializer):
    class Meta:
        model = Room
        fields = ('id', 'room_number',)

class BookingsSerializer(serializers.Serializer):
    ref_id = serializers.CharField()
    room = serializers.ListField(child=RoomSerializer())
    # room = RoomSerializer(many=True)
    check_out_date = serializers.DateField()

# views.py
class ReadBookings(APIView):
    filter = {}
    filter['check_out_date']=check_out_date
    bookings = Booking.objects.filter(**filter)        
    serializer = BookingsSerializer(bookings,many=True)
    return Response(serializer.data) 
enter code here

返回结果

[
    {
    id: 1
    ref_id: "o6eWRjURKP-e4c6d0ca96a145419f528db1a9994029-1609055850117"
    check_out_date: "2020-12-29"
    room:{
        id: 8
        room_number: "006"
    },
    {
    id: 2
    ref_id: "o6eWRjURKP-e4c6d0ca96a145419f528db1a9994029-1609055850117"
    check_out_date: "2020-12-29"
    room:{
        id: 9
        room_number: "007"
    }
]

想要的结果

[
    {
    id: 1
    ref_id: "o6eWRjURKP-e4c6d0ca96a145419f528db1a9994029-1609055850117"
    check_out_date: "2020-12-29"
    rooms:[
            {
                id: 8
                room_number: "006"
            },
            {
                id: 9
                room_number: "007"
            }
         ]
    },
    {
     .........
     .....
    }
]

我认为这是一种可能的解决方案。您可以使用 serializers.SerializerMethodField() 从具有相同 ref_idcheck_out_date 的所有预订中获取所有房间。

class BookingsSerializer(serializers.Serializer):
    ref_id = serializers.CharField()
    rooms = serializers.SerializerMethodField()
    check_out_date = serializers.DateField()

    def get_rooms(self, obj):
        rooms = []
        bookings = Booking.objects.select_related('room')\
                                         .filter(ref_id=obj.ref_id, check_out_date=obj.check_out_date)
        for booking in bookings:
            room = booking.room
            rooms.append({"room_id": room.room_id, "room_number": room.room_number})
        return rooms
bookings_list = [
    {
        "id": 1,
        "ref_id": "o6eWRjURKP-e4c6d0ca96a145419f528db1a9994029-1609055850117",
        "check_out_date": "2020-12-29",
        "room":{
            "id": 8,
            "room_number": "006"
        },
    },
    {
        "id": 2,
        "ref_id": "o6eWRjURKP-e4c6d0ca96a145419f528db1a9994029-1609055850117",
        "check_out_date_id": "2020-12-29",
        "room":{
            "id": 9,
            "room_number": "007"
        }
    }
]

from collections import defaultdict

# check out dates are all the same
check_out_date = bookings_list[0]['check_out_date']

rooms_by_ref_id = defaultdict(list)
# sort rooms lists by ref_id
for b in bookings_list: rooms_by_ref_id[b['ref_id']].append(b['room'])

# populate wanted object
bookings_grouped_rooms_by_ref_id = [
    {'check_out_date': check_out_date, 'ref_id': k, 'rooms': v} 
    for k,v in rooms_by_ref_id.items()
]

我确实从中得到了启发post by kennytm