姜戈。如何在查询结果中添加字段?
Posted
技术标签:
【中文标题】姜戈。如何在查询结果中添加字段?【英文标题】:Django. How do I add a field to a query result? 【发布时间】:2021-03-14 05:48:38 【问题描述】:我有一个 Room 模型,我想将 is_member
布尔字段添加到带有房间的查询集中。怎么能做到这一点?我正在考虑使用.annotate ()
,但这对我的任务不起作用。
models.py
from django.db import models
class Room(models.Model):
name = models.CharField(max_length=150)
members = models.ManyToManyField(User, blank=True)
views.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)
serializers.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__"
我通过这种方式解决了这个问题,但是还有其他选择吗? 请帮帮我
【问题讨论】:
【参考方案1】:你可以试试这个。这不会在查询集中添加 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
]
]
【讨论】:
【参考方案2】:当您使用这样的 M2M 时,您可以使用自己的 through 模型,而不是让 django 自动完成。
这使您能够将自己的字段添加到关系、属性或自定义管理器/查询集。
这方面的文档在这里; https://docs.djangoproject.com/en/3.1/topics/db/models/#extra-fields-on-many-to-many-relationships
因此,通过查询直通模型,您可以确定用户是否是给定房间的成员。
通过模型方法自定义的非常粗略的示例;
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)
【讨论】:
以上是关于姜戈。如何在查询结果中添加字段?的主要内容,如果未能解决你的问题,请参考以下文章