我有两个形成一对多关系的模型。一个货盘具有与其关联的多个图像。
class Pallet(models.Model):
pallet_id = models.IntegerField(primary_key=True)
def __str__(self):
return str(self.pallet_id)
class Meta:
ordering = ('pallet_id',)
class Image(models.Model):
created = models.DateTimeField(auto_now_add=True)
pallet = models.ForeignKey(Pallet, on_delete=models.CASCADE)
image = models.FileField(upload_to="")
def __str__(self):
return str(self.created)
我正在尝试创建一个视图,在该视图中,我从URL中获取所有与特定的Pallet_id相关的图像。
class ImageSerializer(serializers.HyperlinkedModelSerializer):
pallet = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Image
fields = '__all__'
class PalletSerializer(serializers.ModelSerializer):
class Meta:
model = Pallet
fields = '__all__'
urlpatterns = [
url(r'^pallets/', include([
url(r'^(?P<pk>[0-9]+)/$', views.PalletDetail.as_view(), name='pallet-detail'),
])),
]
我认为问题出在PalletDetail类的views.py中。我对如何基于URL的主键编写视图感到困惑。我尝试使用** kwargs ['pk'],但是使用它是否使它成为基于函数的视图?如果是这样,将基于类的视图和基于函数的视图混合会是不好的形式吗?如何从基于类的视图中获得类似的行为?
我真的很在意这里的观点:
class PalletDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Image.objects.prefetch_related('pallet').all()
serializer_class = ImageSerializer
答案 0 :(得分:0)
在基于函数的视图中 传递pk参数 示例:
def Example_function(request, pk):
queryset = Model.objects.filter(id=pk)
在基于类的视图中 获取网址参数
pk = self.kwargs.get('pk')
queryset = Model.objects.filter(id=pk)
答案 1 :(得分:0)
您正在使用序列化程序,并以错误的方式查看。
您的PalletDetail
视图的问题是您使用了错误的查询集。 queryset应该返回Pallet
对象,因为查找将在该queryset上进行(默认查找字段为'pk')。另外,您还需要对Pallet
使用序列化程序,因为它应该处理Pallet
对象的数据。
class PalletDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Pallet.objects.all()
serializer_class = PalletSerializer
答案 2 :(得分:0)
您是否尝试过filter_by()方法
queryset = Model.query.filter_by(id=pk).first()
答案 3 :(得分:0)
您正在以错误的方式进行操作。您要返回属于托盘的图像列表,因此您需要的是图像的列表视图,而不是托盘详细视图。网址应如下所示:
/pallets/<pallet_id>/images/
通过这种方式,URL是自我描述的,并且按照REST标准,您可以轻松地看到您所请求的图像属于托盘而不是托盘本身
在 urls.py
中urlpatterns = [
url(r'^pallets/', include([
url(r'^(?P<pallet_pk>[0-9]+)/images/$', views.PalletImagesListView.as_view(), name='pallet-images-list'),
])),
]
在视图中,您必须覆盖get_queryset()
方法,以便它仅返回指定托盘的图像
class PalletImagesListView(generics.ListAPIView):
serializer_class = ImageSerializer
def get_queryset(self):
return Image.objects.prefetch_related('pallet').filter(pallet__pk=self.kwargs.get('pallet_pk'))
因此,现在您可以使用/pallets/1/images/