#python #django #django-rest-framework #django-serializer
#python #django #django-rest-framework #django-сериализатор
Вопрос:
Я хочу вернуть вложенное представление объектов Customer
with Image
, где Customer
может быть много Images
.
В настоящее время запрос GET возвращает список ВСЕХ изображений из Image
набора запросов для каждого Customer
объекта, как показано ниже. Как я могу вместо этого показывать только связанные Image
(ы) для каждого Customer
объекта в списке?
# The 'images' field currently returns all images rather than related images to the customer id.
[
{
'id': 1,
'name': 'John Doe',
'images': [
{'id': 1, 'name': 'foo.jpg', 'customer': 1},
{'id': 2, 'name': 'bar.jpg', 'customer': 2},
{'id': 3, 'name': 'foobar.jpg', 'customer': 3},
...
]
},
{
'id': 2,
'name': 'Jane Doe',
'images': [
{'id': 1, 'name': 'foo.jpg', 'customer': 1},
{'id': 2, 'name': 'bar.jpg', 'customer': 2},
{'id': 3, 'name': 'foobar.jpg', 'customer': 3},
...
]
},
...
]
Это моя текущая настройка
Примеры моделей
class Customer(models.Model):
name = models.CharField()
class Image(models.Model):
name = models.CharField()
customer = models.ForeignKey(
Customer, on_delete=models.CASCADE)
Примеры сериализаторов
class CustomerSerializer(serializers.ModelSerializer):
# My Customer nested relationship is expressed using ImageSerializer as a field
images = ImageSerializer(many=True)
class Meta:
model = Customer
fields = ('id', 'name', 'images')
read_only_fields = ('id',)
class ImageSerializer(serializers.ModelSerializer):
class Meta:
model = Image
fields = '__all__'
read_only_fields = ('id',)
Пожалуйста, дайте мне знать, если мой вопрос неясен, и я обновлю свой вопрос. Спасибо.
Ответ №1:
Вам нужно использовать связанное имя в качестве поля для обратного внешнего ключа.
В вашем случае это было бы;
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = ('id', 'name', 'image_set')
read_only_fields = ('id',)
Рассматривайте это как обратный FK-запрос — Customer.objects.first().image_set.all()
Документы DRF по этому вопросу находятся здесь; Обратные отношения
Документы Django по изменению отношений находятся здесь
Использование _set
обратного поиска, подобного этому, используется в django по умолчанию. Возможно, вы можете добавить свои собственные related_name
к отношениям.
Пример из документов django;
# Declare the ForeignKey with related_query_name
class Tag(models.Model):
article = models.ForeignKey(
Article,
on_delete=models.CASCADE,
related_name="tags",
related_query_name="tag",
)
name = models.CharField(max_length=255)
# That's now the name of the reverse filter
Article.objects.filter(tag__name="important")
Для вашего примера вы могли бы добавить что-то вроде;
class Image(models.Model):
name = models.CharField()
customer = models.ForeignKey(
Customer,
on_delete=models.CASCADE,
related_name="images"
)
По умолчанию django Customer.image_set
все равно будет работать, но вы можете это сделать, Customer.images.all()
потому что вы определили это related_name
для отношений.
Комментарии:
1. Спасибо, Марк. Раньше я не знал об обратных связях DRF. Спасибо за помощь.