如何覆盖django中的相关字段?
How to override related field in django?
假设我们有这样的模型。
class Product(models.Model):
name = models.CharField(max_length=100)
# ...
main_photo = models.ImageField(upload_to='photos/')
class ProductPhoto(models.Model):
product = models.ForeignKey(Product, related_name='photos', on_delete=models.CASCADE)
photo = models.ImageField(upload_to='photos/')
def __str__(self):
return self.photo.url
我有两种看法:
ProductsView
。它提供了产品列表以及每个产品的一般信息,仅包括 name
、...
、main_photo
。
ProductDetailsView
。它提供了更详细的信息,包括 所有 张照片。
class ProductsView(ListAPIView):
serializer_class = ProductSerializer
class ProductDetailsView(RetrieveAPIView):
serializer_class = ProductDetailsSerializer
序列化程序:
class ProductSerializer(ModelSerializer):
class Meta:
model = Product
fields = ('id', 'name', 'main_photo')
class ProductDetailsSerializer(ModelSerializer):
photos = StringRelatedField(many=True)
class Meta:
model = Product
fields = ('id', 'name', 'main_photo', 'photos')
我想要详细视图以平面阵列 photos
提供所有照片,像这样 [main_photo, ...rest_photos]
。
换一种说法,
回应详细视图而不是这个:
{
"id": 1,
"name": "name",
"main_photo": "/media/photos/main_photo.jpg",
"photos": [
"/media/photos/photo1.jpg",
"/media/photos/photo2.jpg",
"/media/photos/photo3.jpg"
],
}
我想要这个:
{
"id": 1,
"name": "name",
"photos": [
"/media/photos/main_photo.jpg",
"/media/photos/photo1.jpg",
"/media/photos/photo2.jpg",
"/media/photos/photo3.jpg"
],
}
如何使用 django rest 框架执行此操作?这个逻辑应该在哪个层次上实现?模型、视图、序列化程序?
我认为它应该在这里的某个地方,但不太确定它应该是什么样子。
class ProductDetailsView(RetrieveAPIView):
serializer_class = ProductDetailsSerializer
def get_queryset(self):
query_set = Product.objects.all()
# ...
return query_set
对于 url 的照片,在 ProductPhoto
中添加一个 __str__
方法,这将 return 只有 url 的照片
class ProductPhoto(models.Model):
...
def __str__(self):
return self.photo.url
并像这样更改 ProductDetailsSerializer
class ProductDetailsSerializer(ModelSerializer):
photo_list = serializers.SerializerMethodField()
def get_photo_list(self, obj):
db_photos = obj.photos.all()
result = []
if obj.main_photo:
result.append(obj.main_photo.url)
for p in db_photos:
result.append(p.photo.url)
return result
class Meta:
model = Product
fields = ('id', 'name', 'photo_list')
有关 DRF 的更多关系相关文档 check this
假设我们有这样的模型。
class Product(models.Model):
name = models.CharField(max_length=100)
# ...
main_photo = models.ImageField(upload_to='photos/')
class ProductPhoto(models.Model):
product = models.ForeignKey(Product, related_name='photos', on_delete=models.CASCADE)
photo = models.ImageField(upload_to='photos/')
def __str__(self):
return self.photo.url
我有两种看法:
ProductsView
。它提供了产品列表以及每个产品的一般信息,仅包括name
、...
、main_photo
。ProductDetailsView
。它提供了更详细的信息,包括 所有 张照片。
class ProductsView(ListAPIView):
serializer_class = ProductSerializer
class ProductDetailsView(RetrieveAPIView):
serializer_class = ProductDetailsSerializer
序列化程序:
class ProductSerializer(ModelSerializer):
class Meta:
model = Product
fields = ('id', 'name', 'main_photo')
class ProductDetailsSerializer(ModelSerializer):
photos = StringRelatedField(many=True)
class Meta:
model = Product
fields = ('id', 'name', 'main_photo', 'photos')
我想要详细视图以平面阵列 photos
提供所有照片,像这样 [main_photo, ...rest_photos]
。
换一种说法,
回应详细视图而不是这个:
{
"id": 1,
"name": "name",
"main_photo": "/media/photos/main_photo.jpg",
"photos": [
"/media/photos/photo1.jpg",
"/media/photos/photo2.jpg",
"/media/photos/photo3.jpg"
],
}
我想要这个:
{
"id": 1,
"name": "name",
"photos": [
"/media/photos/main_photo.jpg",
"/media/photos/photo1.jpg",
"/media/photos/photo2.jpg",
"/media/photos/photo3.jpg"
],
}
如何使用 django rest 框架执行此操作?这个逻辑应该在哪个层次上实现?模型、视图、序列化程序?
我认为它应该在这里的某个地方,但不太确定它应该是什么样子。
class ProductDetailsView(RetrieveAPIView):
serializer_class = ProductDetailsSerializer
def get_queryset(self):
query_set = Product.objects.all()
# ...
return query_set
对于 url 的照片,在 ProductPhoto
中添加一个 __str__
方法,这将 return 只有 url 的照片
class ProductPhoto(models.Model):
...
def __str__(self):
return self.photo.url
并像这样更改 ProductDetailsSerializer
class ProductDetailsSerializer(ModelSerializer):
photo_list = serializers.SerializerMethodField()
def get_photo_list(self, obj):
db_photos = obj.photos.all()
result = []
if obj.main_photo:
result.append(obj.main_photo.url)
for p in db_photos:
result.append(p.photo.url)
return result
class Meta:
model = Product
fields = ('id', 'name', 'photo_list')
有关 DRF 的更多关系相关文档 check this