[英]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.