webentwicklung-frage-antwort-db.com.de

Wie verwende ich ein Wörterbuch, um Felder in Django-Modellen zu aktualisieren?

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"}
52
TIMEX

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)
81
Thierry Lam

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()
47
leech

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.

0