Поле является обязательным, даже если в сериализаторе оно явно установлено как необязательное
У меня возникли проблемы с маршрутом, создающим/обновляющим модель, DRF запрашивает поле, которое я установил как необязательное, и оно работает с другими сериализаторами, но не со специфическим.
Запрос (здесь нас интересует вложенный объект затрат) :
{
"building_block_id":"bd750fa0-d41d-492d-adc1-9aa7c50db232",
"building_block_type_ids":"6fb5b907-9597-45fd-bb77-e93a2456cca3",
"approbation_user":"",
"approved":false,
"name":"BB2",
"web_doc_link":"",
"author":"",
"cms":"",
"part_number":"",
"manufacturer":"",
"description":"T",
"available_stock":null,
"include_bench_output_connector":true,
"base_repository":"",
"form_factor_id":null,
"direction_bench_side":null,
"cost_references":[
{
"cost":2,
"cost_date":"2021-11-03",
"cost_quantity":2,
"fab_cycle_time_days":2
}
],
"coupling":[
{
"developped":false,
"tested":false,
"validated":false,
"delivered":false,
"valid_link":"",
"implem_link":"",
"software_version_id":"62f4c9f8-1156-4b41-af1a-22041b824d06"
}
],
"comments":[
],
"features":[
],
"provides":[
],
"requires":[
]
}
Ошибка, возвращаемая Django :
{
"coupling": [
{
"building_block_id": [
"This field is required."
]
}
]
}
Класс сериализатора :
class BuildingBlockSerializer(serializers.ModelSerializer):
cost_references = NestedCostReferenceSerializer(many=True, required=False)
coupling = NestedCouplingSerializer(many=True, required=False)
comments = NestedBuildingBlockCommentsSerializer(many=True, required=False)
features = NestedFeaturesBuildingBlockSerializer(many=True, required=False)
provides = NestedProvidesSerializer(many=True, required=False)
requires = NestedRequiresSerializer(many=True, required=False)
main_picture_link = Base64ImageField(required=False)
front_picture_link = Base64ImageField(required=False)
back_picture_link = Base64ImageField(required=False)
# Related names for reverse relationship
cost_reference_rel_name = 'cost_references'
coupling_rel_name = 'coupling'
comment_rel_name = 'comments'
feature_rel_name = 'features'
provide_rel_name = 'provides'
require_rel_name = 'requires'
class Meta:
model = building_blocks.BuildingBlock
fields = ['building_block_id', 'building_block_type_ids', 'approbation_user',
'approved', 'name', 'main_picture_link', 'front_picture_link', 'back_picture_link',
'web_doc_link', 'author', 'cms', 'part_number', 'manufacturer', 'description',
'available_stock', 'include_bench_output_connector', 'base_repository',
'form_factor_id', 'direction_bench_side', 'cost_references', 'coupling',
'comments', 'features', 'provides', 'requires']
optional_fields = ['approved', ]
extra_kwargs = {'approbation_user': {'required': False},
'building_block_type_ids': {'required': False},
'approved': {'required': False, 'allow_null': True},
'main_picture_link': {'required': False},
'front_picture_link': {'required': False},
'back_picture_link': {'required': False},
'web_doc_link': {'required': False},
'author': {'required': False},
'cms': {'required': False},
'part_number': {'required': False},
'manufacturer': {'required': False},
'available_stock': {'required': False, 'allow_null': True},
'include_bench_output_connector': {'required': False},
'base_repository': {'required': False},
'form_factor_id': {'required': False, 'allow_null': True},
'direction_bench_side': {'required': False, 'allow_null': True}}
...
Подсериализатор и вложенный сериализатор :
class CouplingSerializer(serializers.ModelSerializer):
class Meta:
model = building_blocks.Coupling
fields = '__all__'
class NestedCouplingSerializer(CouplingSerializer):
class Meta(CouplingSerializer.Meta):
extra_kwargs = {
"building_block_id": {"required": False},
"building_block_history_id": {"required": False},
}
Модель сцепления :
class Coupling(models.Model):
building_block_id = models.ForeignKey(BuildingBlock, related_name='coupling', on_delete=models.CASCADE)
software_version_id = models.ForeignKey('SoftwaresVersion', on_delete=models.CASCADE)
developped = models.BooleanField()
tested = models.BooleanField()
validated = models.BooleanField()
delivered = models.BooleanField()
valid_link = models.CharField(max_length=256, null=True, blank=True)
implem_link = models.CharField(max_length=256, null=True, blank=True)
class Meta:
unique_together = ['building_block_id', 'software_version_id']
При удалении переменной unique_together
все работает нормально. Я бы хотел оставить эту настройку, но чтобы валидация проходила.
Я пытался установить валидаторы на [], но безрезультатно.
Изменение
unique_together = ['building_block_id', 'software_version_id']
To
constraints = [models.UniqueConstraint(fields=['building_block_id', 'software_version_id'], name='unique_coupling')]
Снято ограничение, вероятно, из-за некоторой валидации поля unique_together
со стороны DRF.