Supposons que j'ai un modèle comme celui-ci:
class Book(models.Model):
num_pages = ...
author = ...
date = ...
Puis-je créer un dictionnaire, puis insérer ou mettre à jour le modèle en l'utilisant?
d = {"num_pages":40, author:"Jack", date:"3324"}
Voici un exemple de création utilisant votre dictionnaire d:
Book.objects.create(**d)
Pour mettre à jour un modèle existant, vous devez utiliser la méthode QuerySet filter
. En supposant que vous connaissiez la pk
du livre que vous souhaitez mettre à jour:
Book.objects.filter(pk=pk).update(**d)
Si vous savez que vous voulez le créer:
Book.objects.create(**d)
En supposant que vous ayez besoin de rechercher une instance existante, vous pouvez la trouver avec get ou create:
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()
Comme mentionné dans une autre réponse, vous pouvez également utiliser la fonction update
sur le gestionnaire de requêtes, mais je pense que cela n'enverra aucun signal (ce qui peut ne pas vous intéresser si vous ne les utilisez pas). Cependant, vous ne devriez probablement pas l'utiliser pour modifier un seul objet:
Book.objects.filter(id=id).update()
Utilisez **
pour créer un nouveau modèle. Parcourez le dictionnaire et utilisez setattr()
afin de mettre à jour un modèle existant.
Cadre de repos Django de Tom Christie
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()
En plus d’autres réponses, voici une version un peu plus sécurisée pour éviter les problèmes avec les champs connexes:
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()
Il vérifie que le champ que vous essayez de mettre à jour est modifiable, qu'il ne s'agit pas d'une clé primaire ni d'un champ associé.
Exemple d'utilisation:
book = Book.objects.first()
update_from_dict(book, {"num_pages":40, author:"Jack", date:"3324"})
Les méthodes .create
et .update
pour les sérialiseurs DRF de luxe disposent d'un ensemble de champs limité et validé, ce qui n'est pas le cas pour la mise à jour manuelle.