我需要在一个请求中更新categories
个Article
。
在ArticleViewSet
我有:
def get_serializer_class(self):
if self.action in ['partial_update', 'update']:
return ArticlePostSerializer
return ArticleSerializer
因此需要更改ArticlePostSerializer
。
这是我的序列化代码:
class ArticleShortCategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = 'id', 'name'
class ArticleSerializer(serializers.ModelSerializer):
categories = serializers.SerializerMethodField()
def get_categories(self, obj):
return ArticleShortCategorySerializer(obj.categories, many=True).data
class Meta:
model = Article
read_only_fields = 'id'
fields = ('categories', 'text') + read_only_fields
class ArticlePostSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = 'id', 'categories', 'text'
我试图添加:
class ArticlePostListSerializer(serializers.ListSerializer):
和
class Meta:
list_serializer_class = ArticlePostListSerializer
但它不起作用。 如何更改此代码以执行多个更新。 我的json请求
{
[id: 90, categories: [10,12,14]],
[id: 93, categories: [10,12,14]],
[id: 95, categories: [10,12,14]]
}
答案 0 :(得分:1)
以下是您请求的CreateMixins或UpdateMixins示例。
=======================查看======================= =========
class OrderCreate(mixins.CreateModelMixin,viewsets.GenericViewSet):
pagination_class = None
def get_queryset(self):
return []
def get_serializer_class(self):
return serializers.OrderSerializer
======================= Serializer ======================= ==
class OrderDetailSerializer(serializers.ModelSerializer):
class Meta:
model = crm_models.OrderDetail
fields = (
'product',
'quantity',
'rate_per_unit',
'order_quantity'
)
class OrderSerializer(serializers.ModelSerializer):
order_details = OrderDetailSerializer(many = True)
class Meta:
model = crm_models.OrderMaster
fields = (
'order',
'invoice_number',
'client',
'beat_check',
'target_customer',
'order_editor_client_employee',
'order_marked',
'order_saved',
'edit_marked',
'edit_saved',
'adhoc',
'order_details'
)
def create(self, validated_data,*args,**kwargs):
ordersdetails_data = validated_data.pop('order_details')
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
validated_data['client'] = user.client
validated_data['order_editor_client_employee'] = user
validated_data['adhoc'] = validated_data['adhoc'] if 'adhoc' in validated_data else False
orderObj = super(OrderSerializer, self).create(validated_data,*args,**kwargs)
orderdetails = []
for details in ordersdetails_data:
orderdetails.append(crm_models.OrderDetail(
product= details['product'],
quantity = details['quantity'],
rate_per_unit = details['rate_per_unit'],
order_quantity = details['order_quantity'],
order = orderObj
))
crm_models.OrderDetail.objects.bulk_create(orderdetails)
return orderObj
在更新视图中,功能名称将更改为更新,您可以找到更多文档 http://www.django-rest-framework.org/api-guide/generic-views/#createmodelmixin
答案 1 :(得分:1)
我发现K. Moe对以下问题的回答:Django Rest Framework POST Update if existing or create更容易理解和实施。您只需要在序列化器中添加一个create方法,并在视图中使用mixins.CreateModelMixin,generics.GenericAPIView。然后,您可以使用POST请求,而不是PUT / PATCH。它允许创建和更新存储在数据库中的数据。我的视图代码:
class ZipCodeList(mixins.CreateModelMixin, generics.GenericAPIView):
def post(self, request, format=None):
is_many = isinstance(request.data, list)
if is_many:
serializer = ZipCodeSerializer(data=request.data, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
serializer = ZipCodeSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
答案 2 :(得分:0)
@Greg Holst,为什么要重复很多?为什么不呢?
class ZipCodeList(mixins.CreateModelMixin, generics.GenericAPIView):
def post(self, request, format=None):
serializer = ZipCodeSerializer(data=request.data, many=isinstance(request.data, list))
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
无论如何,仅对我有用的用于创建新对象,一次也无法创建或更新(它一直告诉我这些对象已经存在),所以这就是我所做的:
class ContributorSyncListAPIView(ListAPIView):
permission_classes = (isSuperUserPermission,)
allowed_methods = ("GET", "PUT")
lookup_field = "airtable_id"
serializer_class = ContributorSyncSerializer # Doesn't get used in Put, just in Get.
model = Contributor
def get_queryset(self):
return self.model.objects.all()
def put(self, request, format=None):
objects = list(request.data)
# objects is a list of OrderedDicts
try:
for o in objects:
try:
instance = self.model.objects.get(
**{self.lookup_field: o.get(self.lookup_field)}
)
for key, value in o.items():
setattr(instance, key, value)
except self.model.DoesNotExist:
instance = self.model(**o)
instance.save()
return Response(objects, status=status.HTTP_200_OK)
except Exception as e:
return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)
请注意,我上面的代码对验证非常轻巧,因为它是由超级用户在具有相同代码库的不同环境中将模型从一个环境同步到另一个环境的过程。因此,假设数据是在将数据输入第一个环境时已经过验证的。为了任何其他目的,您想验证更多。但这是我必须要做的,以逐个对象的方式处理可能需要创建或更新的对象列表。