Un dictionnaire peut-il être transmis aux modèles django lors de la création?

111

Est-il possible de faire quelque chose de similaire avec un list, dictionaryou autre chose?

data_dict = {
    'title' : 'awesome title',
    'body' : 'great body of text',
}

Model.objects.create(data_dict)

Encore mieux si je peux l'étendre:

Model.objects.create(data_dict, extra='hello', extra2='world')
daaawx
la source

Réponses:

211

Si titleet bodysont des champs dans votre modèle, vous pouvez fournir les arguments de mot-clé dans votre dictionnaire à l'aide de l'opérateur ** .

En supposant que votre modèle s'appelle MyModel:

# create instance of model
m = MyModel(**data_dict)
# don't forget to save to database!
m.save()

Quant à votre deuxième question, le dictionnaire doit être l'argument final. Encore une fois, extraet extra2devrait être des champs dans le modèle.

m2 =MyModel(extra='hello', extra2='world', **data_dict)
m2.save()
Alasdair
la source
12
Merci, c'est exactement ce que je cherchais à faire. En outre, en guise de note latérale, basée sur votre message. Vous n'avez pas besoin d'appeler la méthode save lorsque vous utilisez Model.objects.create (** data_dict). Vous le savez probablement déjà, mais juste un avertissement.
4
Je n'ai jamais utilisé la objects.createméthode auparavant, alors vous m'avez appris quelque chose de nouveau.
Alasdair
2
également objects.create renvoie un pointeur vers le nouveau modèle, avec un pk valide rempli. Cela signifie que vous pouvez immédiatement l'utiliser pour créer des modèles associés.
Tom Leys
10
J'ai été mordu par l' ForeignKeyart. Si votre modèle a un ForeignKeyappelé owner, alors vous data_dictdevriez avoir un owner_idchamp. Mais django.forms.model_to_dict()renvoie un dict avec un ownerchamp. Donc vous ne pouvez pas faire MyModel(**model_to_dict(my_instance)); vous devez renommer le ownerchamp en owner_id.
cberzan
La clé étrangère (ajouter _id) ne fonctionnait pas pour moi avec la version 1.5.4. J'ai dû faire quelque chose de plus comme modelinstance.save (), modelinstance.add (Foreignobject.id) pour une relation MTM. Merci quand même. Cela m'a vraiment aidé à me mettre sur la bonne voie pour le faire fonctionner.
RobotHumans
0

Pas directement une réponse à la question, mais je trouve que ce code m'a aidé à créer les dictionnaires qui enregistrent bien dans la bonne réponse. Les conversions de type effectuées sont nécessaires si ces données seront exportées vers json.

J'espère que ça aide:

  #mod is a django database model instance
def toDict( mod ):
  import datetime
  from decimal import Decimal
  import re

    #Go through the object, load in the objects we want
  obj = {}
  for key in mod.__dict__:
    if re.search('^_', key):
      continue

      #Copy my data
    if isinstance( mod.__dict__[key], datetime.datetime ):
      obj[key] = int(calendar.timegm( ts.utctimetuple(mod.__dict__[key])))
    elif isinstance( mod.__dict__[key], Decimal ):
      obj[key] = float( mod.__dict__[key] )
    else:
      obj[key] = mod.__dict__[key]

  return obj 

def toCsv( mod, fields, delim=',' ):
  import datetime
  from decimal import Decimal

    #Dump the items
  raw = []
  for key in fields:
    if key not in mod.__dict__:
      continue

      #Copy my data
    if isinstance( mod.__dict__[key], datetime.datetime ):
      raw.append( str(calendar.timegm( ts.utctimetuple(mod.__dict__[key]))) )
    elif isinstance( mod.__dict__[key], Decimal ):
      raw.append( str(float( mod.__dict__[key] )))
    else:
      raw.append( str(mod.__dict__[key]) )

  return delim.join( raw )
Luke Dupin
la source