Angenommen, ich habe ein Modell wie dieses:
class Book(models.Model):
num_pages = ...
author = ...
date = ...
Kann ich ein Wörterbuch erstellen und anschließend das Modell einfügen oder aktualisieren?
d = {"num_pages":40, author:"Jack", date:"3324"}
Hier ein Beispiel zum Erstellen mit Ihrem Wörterbuch d:
Book.objects.create(**d)
Um ein vorhandenes Modell zu aktualisieren, müssen Sie die QuerySet-Methode filter
verwenden. Angenommen, Sie kennen die pk
des Buches, das Sie aktualisieren möchten:
Book.objects.filter(pk=pk).update(**d)
Wenn Sie wissen, dass Sie es erstellen möchten:
Book.objects.create(**d)
Vorausgesetzt, Sie müssen nach einer vorhandenen Instanz suchen, können Sie sie mit get oder create finden:
instance, created = Book.objects.get_or_create(slug=slug, defaults=d)
if not created:
for attr, value in d.iteritems():
setattr(instance, attr, value)
instance.save()
Wie in einer anderen Antwort erwähnt, können Sie auch die update
-Funktion auf dem Queryset-Manager verwenden, aber ich glaube, dass keine Signale ausgesendet werden (was für Sie möglicherweise keine Rolle spielt, wenn Sie sie nicht verwenden). Sie sollten es jedoch wahrscheinlich nicht verwenden, um ein einzelnes Objekt zu ändern:
Book.objects.filter(id=id).update()
Verwenden Sie **
, um ein neues Modell zu erstellen. Durchlaufen Sie das Wörterbuch und verwenden Sie setattr()
, um ein vorhandenes Modell zu aktualisieren.
Aus Tom Christies Django Rest Framework
https://github.com/tomchristie/Django-rest-framework/blob/master/rest_framework/serializers.py
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
Zusätzlich zu den Antworten gibt es eine etwas sicherere Version, um zu vermeiden, dass verwandte Felder beschädigt werden:
def is_simple_editable_field(field):
return (
field.editable
and not field.primary_key
and not isinstance(field, (ForeignObjectRel, RelatedField))
)
def update_from_dict(instance, attrs, commit):
allowed_field_names = {
f.name for f in instance._meta.get_fields()
if is_simple_editable_field(f)
}
for attr, val in attrs.items():
if attr in allowed_field_names:
setattr(instance, attr, val)
if commit:
instance.save()
Es wird geprüft, dass das Feld, das Sie aktualisieren möchten, bearbeitet werden kann, kein Primärschlüssel und kein verwandtes Feld ist.
Verwendungsbeispiel:
book = Book.objects.first()
update_from_dict(book, {"num_pages":40, author:"Jack", date:"3324"})
Die luxuriösen DRF-Serialisierer-Methoden .create
und .update
bestehen darin, dass es eine begrenzte und validierte Menge von Feldern gibt, was bei der manuellen Aktualisierung nicht der Fall ist.