繁体   English   中英

Django. 如何在查询结果中添加字段?

[英]Django. How do I add a field to a query result?

我有一个房间 model,我想将is_member boolean 字段添加到带有房间的查询集中。 怎么能做到这一点? 我正在考虑使用.annotate () ,但这对我的任务不起作用。

模型.py

from django.db import models

class Room(models.Model):
    name = models.CharField(max_length=150)
    members = models.ManyToManyField(User, blank=True)

视图.py

from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import RoomSerializer
from .models import Room

class RoomView(APIView):
    def get(self, request):
        rooms = Room.objects.all() # get all rooms
        user = request.user # get current user

        for room in rooms:
            members = room.members.all() # get members
            is_member = user in members # set boolean value
            room.is_member = is_member # set in room

        serializer = RoomSerializer(rooms, many=True)
        return Response(serializer.data)

序列化器.py

from rest_framework import serializers
from .models import Room

class RoomSerializer(serializers.ModelSerializer)
    is_member = serializers.BooleanField(read_only=True)
    
    class Meta:
        model = Room
        fields = "__all__"
    

我以这种方式解决了这个问题,但是还有其他选择吗? 请帮帮我

当您使用这样的 M2M 时,您可以通过 model 使用自己的,而不是让 django 自动执行。

这使您能够将自己的字段添加到关系或属性或自定义管理器/查询集。

文档在这里; https://docs.djangoproject.com/en/3.1/topics/db/models/#extra-fields-on-many-to-many-relationships

因此,通过查询 model,您可以确定用户是否是给定房间的成员。

通过 model 方法自定义的一个非常粗略的例子;


class Room(models.Model):
    users = models.ManyToManyField("User", through=ThroughModel)

class User(models.Model):
    text = models.TextField()

class ThroughModel(models.Model):
    room_id = models.ForeignKey(Room)
    user_id = models.ForeignKey(User)
    is_member = models.BooleanField()

# this will return a list of ThroughModel objects
ThroughModel.objects.filter(user=instance_of_user, is_member=True)

# this will return a list of A objects based on an extra field on the through table
Room.objects.filter(users__ThroughModel__is_member=True)

# keep in mind that limiting by one of the foreign keys on the through model is easier
Room.objects.filter(users=instance_of_user)

你能试试这个吗? 这不会在查询集中添加 is_member 但我认为您正在寻找这样的东西。

#  Serializer
class RoomSerializer(serializers.ModelSerializer):
    is_member = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Room
        fields = "__all__"

    def get_is_member(self, obj):
        user = self.context["request"].user
        if user in obj.members.all():
            return True
        return False

#  View
class RoomView(APIView):
    def get(self, request):
        rooms = Room.objects.prefetch_related("members").all()  # get all rooms
        serializer = RoomSerializer(rooms, context={"request": request}, many=True)
        return Response(serializer.data)

你应该得到想要的回应

[
    {
        "id": 1,
        "is_member": true,
        "name": "first",
        "members": [
            1
        ]
    },
    {
        "id": 2,
        "is_member": true,
        "name": "second",
        "members": [
            1,
            2
        ]
    }
]

暂无
暂无

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

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