我正在为一个uni项目开发一个网络应用程序,它是关于机场和航空公司的.
问题
问题是,当我试图以并行方式输入数据库时,因为在我使用的json文件中,有很多关于运营商和机场的条目。
当您逐个更新(PUT和修补程序)时,它按应有的方式工作,但当我尝试PUT/PATCH并行请求时,DB中的实例每次都会被覆盖。
每个机场都有一个运营商列表,当我试图通过PUT或修补程序将更多的运营商添加到该列表时,它将覆盖以前的运营商列表。
我的模特是:
class Carrier(models.Model):
code = models.CharField(max_length=10, primary_key=True)
name = models.TextField()
def __str__(self):
return self.name
class Airport(models.Model):
code = models.CharField(max_length=10, primary_key=True)
name = models.TextField()
carriers = models.ManyToManyField(Carrier, related_name='airports')
def __str__(self):
return self.name
序列化程序:
class AirportListSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='airport-detail')
class Meta:
model = models.Airport
fields = ('code', 'name', 'url')
class AirportDetailSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='airport-detail')
class Meta:
model = models.Airport
fields = ('code', 'name', 'url', 'carriers')
我的更新方法有问题,我不得不重写它,因为要将新数据附加到机场实例的载体数组中:
def update(self, request, *args, **kwargs):
instance = self.get_object()
serializer = serializers.AirportDetailSerializer(
instance=instance,
data=request.data,
context={'request': request}
)
if serializer.is_valid(raise_exception=True):
# Getting the user inputed carriers after it was validated by the serializer
carriers = set(dict(request.data)['carriers'])
# Adding new carriers to the current airport list of carriers without deleting the old ones
for carrier in serializer.validated_data['carriers']:
print(carrier)
carriers.add(carrier)
print('Carriers %s' % carriers)
# Saving alterations to the db
serializer.save(carriers=carriers)
# Overriding the original data for more features
data = serializer.data
# Creating the carrier links
data['carriers'] = ['http://%s/api/carriers/%s/' % (request.get_host(), carrier) for carrier in data['carriers']]
return Response(data)
DRF可浏览API中的条目示例:
发布于 2019-03-16 17:43:02
每次调用serializer.save(carriers=carriers)
时,都只使用特定PUT/修补程序request...rather中的载波来保存Airport
实例,而不是向Airport
实例中添加载波。
您应该查看可写嵌套序列化器的文档,并使用单独的CarrierSerializer
。
与此相关的是,update
逻辑更适合作为AirportSerializer
的一部分,而不是视图。这使得它更可重用。DRF文档的这一部分对您来说是最好的例子。
类似于从专辑/曲目示例中改编的伪代码:
class AirportSerializer(serializers.ModelSerializer):
carriers = CarrierSerializer(many=True)
class Meta:
model = Airport
fields = ......
def update(self, instance, validated_data):
carriers_data = validated_data.pop('carriers')
for carrier in carriers_data:
Carrier.objects.update_or_create(airport=instance, defaults=carrier_data)
return instance
https://stackoverflow.com/questions/55196009
复制相似问题