我正在使用Django + Django rest使用REST架构实现股票经理。
我使用从DefaultRouter继承的自定义路由器为我的端点提供服务。
我在/resources/id
端点中添加了另一个动词POST
,该动词由custom_create
方法调用。
在这里您可以看到此custom_create
方法:
viewsets.py
class ShoeViewSet(viewsets.ModelViewSet):
queryset = Shoe.objects.all()
filter_class = ShoeFilter
def get_serializer_class(self):
if self.action == 'custom_create':
return StockPostSerializer
else:
return ShoeSerializer
def custom_create(self, request, *args, **kwargs):
data = {}
data['shoe'] = kwargs['pk']
data['size'] = request.data.get('size')
data['amount'] = request.data.get('amount')
serializer = self.get_serializer(data=data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
我需要这样做,因为我有两个模型,下面可以看到我的3个序列化器:
serializers.py
class StockSerializer(serializers.ModelSerializer):
class Meta:
model = Stock
fields = ['size', 'amount']
class ShoeSerializer(serializers.ModelSerializer):
stock = StockSerializer(many=True, read_only=True)
class Meta:
model = Shoe
fields = ['description', 'provider', 'type', 'cost_price','sale_price','total_amount', 'stock']
class StockPostSerializer(serializers.ModelSerializer):
class Meta:
model = Stock
fields = ['shoe','size', 'amount']
此终结点的retrieve
(GET
动词)方法期望由ShoeSerializer
序列化的数据,但是custom_create
方法使用StockPostSerializer
插入数据。如何返回插入了其他数据的响应?
当我尝试使用此端点插入时,我收到this错误消息,但是当我刷新页面时,我意识到内容已插入(如果我使用邮递员而不是de DRF前端,则不会收到任何错误消息,效果很好)。
我的custom_create
方法如何正确响应?
您可以检查我的github,名称会有所不同,因为我在这里进行了翻译,以便您理解。
PS :您可能已经注意到,我不是英语母语人士,因此在这里表达自己的观点非常困难,但我正在尽力而为,并不断学习。如果我的问题包含语法/一致性错误,请更正它们,但您不必拒绝我,因此我正在尝试学习!
答案 0 :(得分:1)
如果通过查看您的代码我能正确理解,那么在这种情况下,则不需要StockPostSerializer
。您可以通过如下更改StockSerializer
来获得所需的结果:
class StockSerializer(serializers.ModelSerializer):
class Meta:
model = Stock
fields = ['shoe', 'size', 'amount']
extra_kwargs = {'shoe': {'write_only': True}}
如果我误解了你的问题,我深表歉意。
编辑:
忘了说。使用此序列化程序,您的ModelViewSet
答案 1 :(得分:0)
我终于设法解决了这个问题,并且比以前尝试的要优雅得多。
我需要做的是:添加新的库存实例,为此,我在端点资源/标识中为POST创建了新的路由。
因此,我能够重用默认路由器,删除custom_create
方法,并修改了serializers.py文件。
看起来像这样:
serializers.py
class StockSerializer(serializers.ModelSerializer):
class Meta:
model = Stock
fields = ['size', 'amount']
class ShoeSerializer(serializers.ModelSerializer):
stock = StockSerializer(many=True)
def update(self, instance, validated_data):
instance.description = validated_data.get(
'description', instance.description)
instance.provider = validated_data.get(
'provider', instance.provider)
instance.type = validated_data.get('type', instance.type)
instance.cost_price = validated_data.get(
'cost_price', instance.cost_price)
instance.salve_price = validated_data.get(
'sale_price', instance.sale_price)
stock = instance.stock.all()
stock_data = validated_data.get('stock', [])
for item_data in stock_data:
item_id = item_data.get('size', None)
if item_id is not None:
item_db = stock.get(size=item_id)
item_db.size = item_data.get('size', item_db.size)
item_db.amount = item_data.get('amount',item_db.amount)
item_db.save()
else:
Estoque.objects.create(
shoe = instance,
size = item_data['size'],
amount = item_data['amount']
)
instance.save()
return instance
class Meta:
model = Shoe
fields = ['_id','description', 'provider', 'type', 'cost_price','sale_price','total_amount', 'stock']
现在,通过PATCH
动词,我可以添加新的Stock实例并更改现有的Stock实例。谢谢您的支持!