python - example - django rest framework serializer
Obteniendo el error "no existe o es m2m field" en mi uuid(clave principal) cuando intento guardar en DRF (1)
ListSerializer
mi propio ListSerializer
masivo save()
porque no puedo obtener el método interno save()
de ListSerializer
para llamar al método relevante ( create()
y update()
) dependiendo de la carga útil de la consulta. El modelo se llama Product
cuya clave principal es un uuid
. Cuando llamo al método save()
enlazado de Product con el updated_fields
los updated_fields
actualizados, obtengo:
ValueError: los siguientes campos no existen en este modelo o son campos m2m: uuid
Aquí está save()
:
def save(self):
instances = []
result = []
# Note self.validated_data is a list of multiple OrderedDicts representing
# the json of Product fields. Depending on the request, they will either
# have uuids (so we will update these instances), or won''t and hence
# require creation.
for obj in self.validated_data:
uuid = obj.get(''uuid'', None)
if uuid:
instance = get_object_or_404(Product, uuid=uuid)
update_fields = [k for k,v in obj.items()]
for k, v in obj.items():
setattr(instance, k, v)
instance.save(update_fields=update_fields)
result.append(instance)
else:
instances.append(Product(**obj))
Product.objects.bulk_create(instances)
result += instances
return result
Aquí está la parte relevante de la cola del rastreo:
Archivo "/my/app/views/API/product.py", línea 162, en partial_update serializer.save ()
Archive "/my/app/views/API/serializers.py", línea 72, en save update_fields = [k para k, v en obj.items ()]
Archivo "/lib/python3.5/site-packages/django/db/models/base.py", línea 792, en save% '','' .join (non_model_fields))
ValueError: los siguientes campos no existen en este modelo o son campos m2m: uuid
Aquí está la parte relevante de la definición del Product
:
class Product(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
Entonces, no es un m2m, y ese campo existe. ¿Cuál es la causa de este error?
El error proviene de esta línea donde Django compara update_fields
que proporcionó con los campos del Modelo.
if non_model_fields:
raise ValueError("The following fields do not exist in this "
"model or are m2m fields: %s"
% '', ''.join(non_model_fields))
Desafortunadamente, el mensaje de error es un poco engañoso porque todos los campos con primary_key=True
(como su campo uuid
) se filtran , al lado de m2m
ones.
update_fields = frozenset(update_fields)
field_names = set()
for field in self._meta.fields:
if not field.primary_key:
field_names.add(field.name)
...
non_model_fields = update_fields.difference(field_names)
Esa es la razón por la cual non_model_fields
no está vacío y se non_model_fields
excepción.
Para solucionar su problema, debe deshacerse de la clave uuid
de obj
antes de guardar.
...
obj.pop(''uuid'') # only if mutating validated_data doesn''t bother you
update_fields = [k for k,v in obj.items()]
for k, v in obj.items():
setattr(instance, k, v)
instance.save(update_fields=update_fields)
result.append(instance)
Por cierto, no necesita esta lista de comprensión para obtener update_fields
- puede usar obj.keys()
que da el mismo resultado.