DRF 中 ModelSerializer 中创建和更新方法中的重复代码
Duplicated code in create and update methods inside ModelSerializer in DRF
我创建了一个 ModelSerializer,我在其中覆盖了默认的创建和更新方法,发现代码几乎相同。它负责保存图像(通过 FK 连接)和匹配 PaymentMethods(通过 M2M 连接)以创建和替换 Images 和 PaymentMethods 在更新的情况下,但主要验证和创建逻辑是相同的。有什么办法可以缩短这个吗?到目前为止,我还没有找到任何关于这种可能性的资源。
class TruckSerializer(serializers.ModelSerializer):
location = LocationSerializer(read_only=True,)
owner = serializers.PrimaryKeyRelatedField(read_only=True,)
class Meta:
model = Truck
fields = "__all__"
def create(self, validated_data):
data = self.context.get("view").request.data
if data.get("payment"):
new_payments = []
payments = data.get("payment")
for payment in payments.split(", "):
try:
filtered_payment = PaymentMethod.objects.get(
payment_name__iexact=payment).id
except PaymentMethod.DoesNotExist:
raise serializers.ValidationError(
'Given payment method does not match')
new_payments.append(filtered_payment)
truck = Truck.objects.create(**validated_data) <---- valid only in create
truck.payment_methods.add(*new_payments)
if data.get("image"):
for image_data in data.getlist("image"):
TruckImage.objects.create(truck=truck, image=image_data)
return truck
def update(self, instance, validated_data):
data = self.context.get("view").request.data
if data.get("payment"):
new_payments = []
payments = data.get("payment")
for payment in payments.split(", "):
try:
filtered_payment = PaymentMethod.objects.get(
payment_name__iexact=payment).id
except PaymentMethod.DoesNotExist:
raise serializers.ValidationError(
'Given payment method does not match')
new_payments.append(filtered_payment)
instance.payment_methods.clear() <---- valid only in update
instance.payment_methods.add(*new_payments)
if data.get("image"):
images = instance.images.all()
if images.exists(): <---- valid only in update
instance.images.all().delete()
for image_data in data.getlist("image"):
TruckImage.objects.create(truck=instance, image=image_data)
return super(TruckSerializer, self).update(instance, validated_data)
您可以定义一个新方法来处理您的重复代码。引入新方法后,您的 class 现在看起来像这样。
class TruckSerializer(serializers.ModelSerializer):
# your existing code....
def get_new_payments(self):
data = self.context.get("view").request.data
if data.get("payment"):
new_payments = []
payments = data.get("payment")
for payment in payments.split(", "):
try:
filtered_payment = PaymentMethod.objects.get(
payment_name__iexact=payment).id
except PaymentMethod.DoesNotExist:
raise serializers.ValidationError(
'Given payment method does not match')
new_payments.append(filtered_payment)
return new_payments
def create(self, validated_data):
new_payments = self.get_new_payments() # will return new_payments
truck = Truck.objects.create(**validated_data)
truck.payment_methods.add(*new_payments)
if data.get("image"):
for image_data in data.getlist("image"):
TruckImage.objects.create(truck=truck, image=image_data)
return truck
def update(self, instance, validated_data):
new_payments = self.get_new_payments() # will return new_payments
instance.payment_methods.clear()
instance.payment_methods.add(*new_payments)
if data.get("image"):
images = instance.images.all()
if images.exists():
instance.images.all().delete()
for image_data in data.getlist("image"):
TruckImage.objects.create(truck=instance, image=image_data)
return super(TruckSerializer, self).update(instance, validated_data)
我创建了一个 ModelSerializer,我在其中覆盖了默认的创建和更新方法,发现代码几乎相同。它负责保存图像(通过 FK 连接)和匹配 PaymentMethods(通过 M2M 连接)以创建和替换 Images 和 PaymentMethods 在更新的情况下,但主要验证和创建逻辑是相同的。有什么办法可以缩短这个吗?到目前为止,我还没有找到任何关于这种可能性的资源。
class TruckSerializer(serializers.ModelSerializer):
location = LocationSerializer(read_only=True,)
owner = serializers.PrimaryKeyRelatedField(read_only=True,)
class Meta:
model = Truck
fields = "__all__"
def create(self, validated_data):
data = self.context.get("view").request.data
if data.get("payment"):
new_payments = []
payments = data.get("payment")
for payment in payments.split(", "):
try:
filtered_payment = PaymentMethod.objects.get(
payment_name__iexact=payment).id
except PaymentMethod.DoesNotExist:
raise serializers.ValidationError(
'Given payment method does not match')
new_payments.append(filtered_payment)
truck = Truck.objects.create(**validated_data) <---- valid only in create
truck.payment_methods.add(*new_payments)
if data.get("image"):
for image_data in data.getlist("image"):
TruckImage.objects.create(truck=truck, image=image_data)
return truck
def update(self, instance, validated_data):
data = self.context.get("view").request.data
if data.get("payment"):
new_payments = []
payments = data.get("payment")
for payment in payments.split(", "):
try:
filtered_payment = PaymentMethod.objects.get(
payment_name__iexact=payment).id
except PaymentMethod.DoesNotExist:
raise serializers.ValidationError(
'Given payment method does not match')
new_payments.append(filtered_payment)
instance.payment_methods.clear() <---- valid only in update
instance.payment_methods.add(*new_payments)
if data.get("image"):
images = instance.images.all()
if images.exists(): <---- valid only in update
instance.images.all().delete()
for image_data in data.getlist("image"):
TruckImage.objects.create(truck=instance, image=image_data)
return super(TruckSerializer, self).update(instance, validated_data)
您可以定义一个新方法来处理您的重复代码。引入新方法后,您的 class 现在看起来像这样。
class TruckSerializer(serializers.ModelSerializer):
# your existing code....
def get_new_payments(self):
data = self.context.get("view").request.data
if data.get("payment"):
new_payments = []
payments = data.get("payment")
for payment in payments.split(", "):
try:
filtered_payment = PaymentMethod.objects.get(
payment_name__iexact=payment).id
except PaymentMethod.DoesNotExist:
raise serializers.ValidationError(
'Given payment method does not match')
new_payments.append(filtered_payment)
return new_payments
def create(self, validated_data):
new_payments = self.get_new_payments() # will return new_payments
truck = Truck.objects.create(**validated_data)
truck.payment_methods.add(*new_payments)
if data.get("image"):
for image_data in data.getlist("image"):
TruckImage.objects.create(truck=truck, image=image_data)
return truck
def update(self, instance, validated_data):
new_payments = self.get_new_payments() # will return new_payments
instance.payment_methods.clear()
instance.payment_methods.add(*new_payments)
if data.get("image"):
images = instance.images.all()
if images.exists():
instance.images.all().delete()
for image_data in data.getlist("image"):
TruckImage.objects.create(truck=instance, image=image_data)
return super(TruckSerializer, self).update(instance, validated_data)