Django嵌套Serializer过滤到只有一个字段,而不是所有字段
Django nested Serializer filter to only one field, not all fields
我有两个如下所示的序列化程序。以下代码段的输出是 Workers 以及包含所有字段 (ticket_counter
、ticket_counter_name
、worker
) 的相关票务柜台详细信息。但我只需要一个字段,即 ticket_counter_name
。
class WorkerSerializer(serializers.ModelSerializer):
ticket_counter = WorkerToCounterSerializer(many=True, read_only=True)
class Meta:
model = User
fields = (
'username',
'ticket_counter',
)
class WorkerToCounterSerializer(serializers.ModelSerializer):
ticket_counter = SerializerMethodField()
ticket_counter_name = serializers.CharField(source='ticket_counter.ticket_counter_name')
class Meta:
model = WorkerToTicketCounter
list_serializer_class = FilteredListSerializer
fields = (
'ticket_counter',
'ticket_counter_name',
'worker',
)
def get_ticket_counter(self, obj):
return obj.ticket_counter.pk
class FilteredListSerializer(ListSerializer):
def to_representation(self, data):
data = data.filter(worker_to_ticket_counter_is_deleted=False)[:1]
return super(FilteredListSerializer, self).to_representation(data)
上面的代码片段输出了什么
{
"username": "xxxxxxxxxxx",
"ticket_counter": [
{
"ticket_counter": 7,
"ticket_counter_name": "Entrance Counter",
"worker": 4,
}
]
}
但我想要的是
{
"username": "xxxxxxxxxxx",
"ticket_counter": "Entrance Counter"
}
我只需要 ticket_counter_name
的名称。就我而言,一个工人不能有两个 ticket_counters。显然,它只给出了一个ticket_counter
。可能吗?
编辑:使用字符串 StringRelatedField
{
"username": "xxxxxxxxxxx",
"ticket_counter": [
"Entrance Counter",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx"
]
}
编辑:WorkerToTicketCounter
型号
class WorkerToTicketCounter(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
ticket_counter = models.ForeignKey(TicketCounter, related_name="workers")
worker = models.ForeignKey(User, related_name='ticket_counter')
worker_to_ticket_counter_is_deleted = models.BooleanField(default=False)
您可以使用 StringRelatedField
:
class WorkerSerializer(serializers.ModelSerializer):
ticket_counter = StringRelatedField(many=True, read_only=True)
class Meta:
model = User
fields = (
'username',
'ticket_counter',
)
使用 StringRelatedField
的注意事项您应该将 __str__
方法添加到您的 WorkerToTicketCounter
模型:
class WorkerToTicketCounter:
...
def __str__(self):
return self.ticket_counter.ticket_counter_name
如果我没理解错的话,你只需要一个 SerializerMethodField 来执行两个 filtering和字符串表示.
class WorkerSerializer(serializers.ModelSerializer):
<b>ticket_counter = serializers.SerializerMethodField(read_only=True)
def get_ticket_counter(self, user):
qs = user.ticket_counter.filter(worker_to_ticket_counter_is_deleted=False)
if qs.exists() and hasattr(qs.first().ticket_counter, 'ticket_counter_name'):
return qs.first().ticket_counter.ticket_counter_name
return None</b>
class Meta:
model = User
fields = ('username', 'ticket_counter',)
我有两个如下所示的序列化程序。以下代码段的输出是 Workers 以及包含所有字段 (ticket_counter
、ticket_counter_name
、worker
) 的相关票务柜台详细信息。但我只需要一个字段,即 ticket_counter_name
。
class WorkerSerializer(serializers.ModelSerializer):
ticket_counter = WorkerToCounterSerializer(many=True, read_only=True)
class Meta:
model = User
fields = (
'username',
'ticket_counter',
)
class WorkerToCounterSerializer(serializers.ModelSerializer):
ticket_counter = SerializerMethodField()
ticket_counter_name = serializers.CharField(source='ticket_counter.ticket_counter_name')
class Meta:
model = WorkerToTicketCounter
list_serializer_class = FilteredListSerializer
fields = (
'ticket_counter',
'ticket_counter_name',
'worker',
)
def get_ticket_counter(self, obj):
return obj.ticket_counter.pk
class FilteredListSerializer(ListSerializer):
def to_representation(self, data):
data = data.filter(worker_to_ticket_counter_is_deleted=False)[:1]
return super(FilteredListSerializer, self).to_representation(data)
上面的代码片段输出了什么
{
"username": "xxxxxxxxxxx",
"ticket_counter": [
{
"ticket_counter": 7,
"ticket_counter_name": "Entrance Counter",
"worker": 4,
}
]
}
但我想要的是
{
"username": "xxxxxxxxxxx",
"ticket_counter": "Entrance Counter"
}
我只需要 ticket_counter_name
的名称。就我而言,一个工人不能有两个 ticket_counters。显然,它只给出了一个ticket_counter
。可能吗?
编辑:使用字符串 StringRelatedField
{
"username": "xxxxxxxxxxx",
"ticket_counter": [
"Entrance Counter",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx"
]
}
编辑:WorkerToTicketCounter
型号
class WorkerToTicketCounter(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
ticket_counter = models.ForeignKey(TicketCounter, related_name="workers")
worker = models.ForeignKey(User, related_name='ticket_counter')
worker_to_ticket_counter_is_deleted = models.BooleanField(default=False)
您可以使用 StringRelatedField
:
class WorkerSerializer(serializers.ModelSerializer):
ticket_counter = StringRelatedField(many=True, read_only=True)
class Meta:
model = User
fields = (
'username',
'ticket_counter',
)
使用 StringRelatedField
的注意事项您应该将 __str__
方法添加到您的 WorkerToTicketCounter
模型:
class WorkerToTicketCounter:
...
def __str__(self):
return self.ticket_counter.ticket_counter_name
如果我没理解错的话,你只需要一个 SerializerMethodField 来执行两个 filtering和字符串表示.
class WorkerSerializer(serializers.ModelSerializer):
<b>ticket_counter = serializers.SerializerMethodField(read_only=True)
def get_ticket_counter(self, user):
qs = user.ticket_counter.filter(worker_to_ticket_counter_is_deleted=False)
if qs.exists() and hasattr(qs.first().ticket_counter, 'ticket_counter_name'):
return qs.first().ticket_counter.ticket_counter_name
return None</b>
class Meta:
model = User
fields = ('username', 'ticket_counter',)