update tutorial serializermethodfield framework def create allow django django-rest-framework

serializermethodfield - django rest framework tutorial



Django REST Framework: validaciĆ³n de Unique_together en Serializadores (6)

Tener problemas con un serializer.is_valid() devolviendo True si la instancia del serializador falla una restricción unique_together en el lado del modelo.

¿Hay alguna manera de que yo especifique en el serializador para imponer una restricción unique_together ?


Bueno, esto es un poco estúpido y es muy poco probable que alguien que no sea yo cometa este error, pero había puesto el mismo modelo en dos clases de serializadores, como consecuencia tuve este problema.

Espero que mi error ayude a alguien!


Desafortunadamente, la respuesta de Andreas no es del todo completa, ya que no funcionará en el caso de una actualización.

En su lugar, querrías algo más como:

def validate(self, attrs): field1 = attrs.get(''field1'', self.object.field1) field2 = attrs.get(''field2'', self.object.field2) try: obj = Model.objects.get(field1=field1, field2=field2) except StateWithholdingForm.DoesNotExist: return attrs if self.object and obj.id == self.object.id: return attrs else: raise serializers.ValidationError(''field1 with field2 already exists'')

Esto funcionará para PUT, PATCH y POST.


La clase ModelSerializer tiene esta funcionalidad incorporada, al menos en djangorestframework>=3.0.0 , sin embargo, si está utilizando un serializer que no incluye todos los campos que se ven afectados por su restricción unique_together , obtendrá una IntegrityError al guardar una instancia que la viola. Por ejemplo, usando el siguiente modelo:

class Foo(models.Model): class Meta: unique_together = (''foo_a'', ''foo_b'') a = models.TextField(blank=True) b = models.TextField(blank=True) foo_a = models.IntegerField() foo_b = models.IntegerField(default=2)

y el siguiente serializador y ViewSet:

class FooSerializer(serializers.ModelSerializer): class Meta: model = models.Foo fields = (''a'', ''b'', ''foo_a'') class FooViewSet(viewsets.ModelViewSet): queryset = models.Foo.objects.all() serializer_class = FooSerializer routes = routers.DefaultRouter() routes.register(r''foo'', FooViewSet)

Si intenta guardar dos instancias con el mismo conjunto foo_a y foo_b , obtendrá un IntegrityError . Sin embargo, si modificamos el serializador de esta manera:

class FooSerializer(serializers.ModelSerializer): class Meta: model = models.Foo fields = (''a'', ''b'', ''foo_a'', ''foo_b'')

a continuación, obtendrá un código de estado HTTP 400 BAD REQUEST y el correspondiente mensaje descriptivo JSON en el cuerpo de la respuesta:

HTTP 400 BAD REQUEST Content-Type: application/json Vary: Accept Allow: GET, POST, HEAD, OPTIONS { "non_field_errors": [ "The fields foo_a, foo_b must make a unique set." ] }

Espero que esto te resulte útil, incluso cuando esta es una pregunta un poco antigua ;-)


Necesitaba esto para anular el mensaje predeterminado. Resuelto por this .

from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers class SomeSerializer(serializers.ModelSerializer): """ Demostrating How to Override DRF UniqueTogetherValidator Message """ class Meta: model = Some validators = [ serializers.UniqueTogetherValidator( queryset=model.objects.all(), fields=(''field1'', ''field2''), message=_("Some custom message.") ) ]

Similarly you can specify fields


Sí, puede hacerlo en el método .validate() del serializador.

def validate(self, attrs): try: Model.objects.get(field1=attrs[''field1''], field2=attrs[''field2'']) except Model.DoesNotExist: pass else: raise serializers.ValidationError(''field1 with field2 already exists'') return attrs

La restricción única que estableció en su modelo es para crear restricciones de base de datos, no para validar.


Tenía el mismo problema y de esta respuesta, https://.com/a/26027788/6473175 , pude hacer que funcionara, pero tuve que usar self.instance lugar de self.object .

def validate(self, data): field1 = data.get(''field1'',None) field2 = data.get(''field2'',None) try: obj = self.Meta.model.objects.get(field1=field1, field2=field2) except self.Meta.model.DoesNotExist: return data if self.instance and obj.id == self.instance.id: return data else: raise serializers.ValidationError(''custom error message'')