Условие, является ли поле A или B обязательным в Django Rest Framework
У меня есть сериализатор, в котором я хотел бы дать возможность отправить НОВЫЙ адрес с POST-запросом ИЛИ указать ID уже существующего адреса. Требуется одно из двух, но сейчас он просит указать оба варианта.
Есть ли возможность добиться того, чтобы он подтверждал условие?
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
#fields = '__all__'
exclude = ['in_calculation','canceled',]
address = AdressSerializer()
addressid = serializers.CharField(source='address')
read_only_fields = ['id','user','status','costs','']
Вы можете использовать validate()
и настроенный метод create
/update
следующим образом:
class OrderSerializer(serializers.ModelSerializer):
address_detail = AddressSerializer(write_only=True, required=False)
class Meta:
model = Order
fields = (
'address', # to set from an existing address
'address_detail', # to create a whole new address
)
extra_kwargs = {
'address': {'required': False}, # make `address` to optional if your address in model is required.
}
def validate(self, attrs):
# if `address` and `address_detail` are both present or none of them is present
if bool('address' in attrs) == bool('address_detail' in attrs):
raise serializers.ValidationError('You can specify exactly one from these two fields.')
return attrs
def create(self, validated_data):
# do custom logic
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
extra_kwargs = {
'address': {'required': False},
}
exclude = [] # some fields that should not be shown
read_only_fields = [] # some fields that should not be edited
# Add a nested Serializer to add new addresses while creating an order
address_detail = addressSerializer(required=False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
try:
if "GET" in self.context['request'].method:
self.fields['client'] = ClientSerializer()
# ... some Nested Serializers which are ready-only on GET request.
except KeyError:
pass
def create(self,validated_data):
# check for uniqueness of ordernr and clientnr
try:
order = Order.objects.get(client=validated_data.get('client'),ordernr=validated_data.get('ordernr'))
if order:
raise ValidationError({'ordernr':'Ordernumber and Client-combination already exists'})
except ObjectDoesNotExist:
if validated_data.get('address_detail'):
address_detail = validated_data.pop('address_detail')
if address_detail:
address, existent = address.objects.get_or_create(**address_detail)
order = Order.objects.create(**validated_data, address=address)
elif validated_data.get('address'):
order = Order.objects.create(**validated_data)
return order
def validate(self, data):
validationerrors = {}
print(data)
# if `address` and `address_detail` are both present or none of them is present
if bool('address' in data) == bool('address_detail' in data):
validationerrors['address'] = "You need to specify exactly one from these two fields."
# a lot of other validations...
if validationerrors:
raise serializers.ValidationError(validationerrors)
return data