Rah*_*rma 1 python django django-rest-framework
在我的 Django 应用程序中,我在Orders和之间有一个多对多关系Packages。一个订单可以有多个包裹。我想了解更新和创建方法
模型.py
class Package(models.Model):
prod_name = models.CharField(max_length=255, default=0)
quantity = models.IntegerField(default=0)
unit_price = models.IntegerField(default=0)
class Orders(models.Model):
order_id = models.CharField(max_length=255, default=0)
package = models.ManyToManyField(Package)
is_cod = models.BooleanField(default=False)
Run Code Online (Sandbox Code Playgroud)
序列化器.py
class PackageSerializer(serializers.ModelSerializer):
class Meta:
model = Package
fields = "__all__"
class OrderSerializer(serializers.ModelSerializer):
package = PackageSerializer(many=True)
class Meta:
model = Orders
fields = "__all__"
Run Code Online (Sandbox Code Playgroud)
视图.py
class OrdersCreateAPIView(generics.CreateAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = OrderSerializer
def post(self, request):
serializer = OrderSerializer(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)
Run Code Online (Sandbox Code Playgroud)
这足以处理相关数据吗?我试图了解ManytoManyDjango 和 DRF 中的关系,所以请解释我是否需要更改模型或视图
更新:
我已经更新了我的序列化程序和视图,以便创建这样的manytomany相关对象:
class OrderSerializer(serializers.ModelSerializer):
package = PackageSerializer(many=True)
class Meta:
model = Orders
fields = "__all__"
def create(self, validated_data):
package_data = validated_data.pop('package')
pkgs = []
order = Orders.objects.create(**validated_data)
for i in package_data:
try:
p = Package.objects.create(**i)
pkgs.append(p)
except:
pass
order.package.set(pkgs)
return order
Run Code Online (Sandbox Code Playgroud)
视图.py
class OrdersCreateAPIView(CreateAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = OrderSerializer
def perform_create(self,serializer):
serializer.save(owner=self.request.user)
Run Code Online (Sandbox Code Playgroud)
但是我仍然不清楚重写update的方法RetrieveUpdateDestroyAPIView。另外,上述方法是存储M2M相关对象的正确方法吗?
请帮助序列化程序的更新部分,我知道我必须在序列化程序中传递查询
#serializers.py
class PackageSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
class Meta:
model = Package
fields = "__all__"
class OrderSerializer(serializers.ModelSerializer):
package = PackageSerializer(many=True)
def get_or_create_packages(self, packages):
package_ids = []
for package in packages:
package_instance, created = Package.objects.get_or_create(pk=package.get('id'), defaults=package)
package_ids.append(package_instance.pk)
return package_ids
def create_or_update_packages(self, packages):
package_ids = []
for package in packages:
package_instance, created = Package.objects.update_or_create(pk=package.get('id'), defaults=package)
package_ids.append(package_instance.pk)
return package_ids
def create(self, validated_data):
package = validated_data.pop('package', [])
order = Orders.objects.create(**validated_data)
order.package.set(self.get_or_create_packages(package))
return order
def update(self, instance, validated_data):
package = validated_data.pop('package', [])
instance.package.set(self.create_or_update_packages(package))
fields = ['order_id', 'is_cod']
for field in fields:
try:
setattr(instance, field, validated_data[field])
except KeyError: # validated_data may not contain all fields during HTTP PATCH
pass
instance.save()
return instance
class Meta:
model = Orders
fields = "__all__"
#views.py
class OrderViewSet(viewsets.ModelViewSet):
serializer_class = OrderSerializer
queryset = Orders.objects.all()
Run Code Online (Sandbox Code Playgroud)
在DefaultRouteras的帮助下注册此视图,
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'order', OrderViewSet, basename='order')
urlpatterns = [
] + router.urls
Run Code Online (Sandbox Code Playgroud)
因此,您将获得该表中所述的基本 CRUD 端点(请参阅DefaultRouter参考资料)。
让您的订单列表终点为/foo-bar/order/
/foo-bar/order/创建新实例/foo-bar/order/<ORDER_PK>/来更新内容在这种情况下,id如果您希望将现有的包关系与Order
你可以像这样连接视图
urlpatterns = [
path('foo/order/', OrderViewSet.as_view({'post': 'create'})), # create new Order instance
path('foo/order/<int:pk>/', OrderViewSet.as_view({'patch': 'partial_update'})), # update Order instance
]
Run Code Online (Sandbox Code Playgroud)
注意:这仅支持HTTP POST和HTTP PATCH
| 归档时间: |
|
| 查看次数: |
1801 次 |
| 最近记录: |