I have created a ModelSerializer where I override default create and update methods and found the code to be pretty much the same. It is responsible for saving Images (connected via FK) and matching PaymentMethods (connected via M2M) in case of creating and replace Images and PaymentMethods in case of updating but the main validation and creation logic is the same. Is there any way to shorten this? I haven't found so far any resources for this possibility.
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)
question from:
https://stackoverflow.com/questions/65843985/duplicated-code-in-create-and-update-methods-inside-modelserializer-in-drf 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…