Czy słownik można przekazać do modeli django podczas tworzenia?

111

Czy to możliwe, aby zrobić coś podobnego do tego z list, dictionarylub coś innego?

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

Model.objects.create(data_dict)

Jeszcze lepiej, jeśli mogę to przedłużyć:

Model.objects.create(data_dict, extra='hello', extra2='world')
daaawx
źródło

Odpowiedzi:

211

Jeśli titlei bodysą polami w Twoim modelu, możesz dostarczyć argumenty słów kluczowych w słowniku za pomocą operatora ** .

Zakładając, że twój model nazywa się MyModel:

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

Jeśli chodzi o drugie pytanie, ostatecznym argumentem musi być słownik. Ponownie, extrai extra2powinny być pola w modelu.

m2 =MyModel(extra='hello', extra2='world', **data_dict)
m2.save()
Alasdair
źródło
12
Dzięki, dokładnie to chciałem zrobić. Ponadto, na marginesie, opartym tylko na Twoim poście. Nie musisz wywoływać metody save, gdy używasz Model.objects.create (** data_dict). Prawdopodobnie już to wiesz, ale tylko jedno ostrzeżenie.
4
Nie korzystałem wcześniej z tej objects.createmetody, więc nauczyłeś mnie czegoś nowego.
Alasdair
2
również objects.create zwraca wskaźnik do nowego modelu z wypełnionym prawidłowym pakietem. Oznacza to, że można go natychmiast użyć do zbudowania powiązanych modeli.
Tom Leys
10
Zostałem ugryziony przez ForeignKeys. Jeśli twój model ma ForeignKeywywołanie owner, to data_dictpowinieneś mieć owner_idpole. Ale django.forms.model_to_dict()zwraca dykt z ownerpolem. Więc nie możesz tego zrobić MyModel(**model_to_dict(my_instance)); musisz zmienić nazwę ownerpola na owner_id.
cberzan
Klucz obcy (dodanie _id) nie działał dla mnie w wersji 1.5.4. Musiałem zrobić coś bardziej jak modelinstance.save (), modelinstance.add (Foreignobject.id) dla relacji MTM. W każdym razie dzięki. To naprawdę pomogło mi wejść na właściwą ścieżkę, aby to działało.
RobotHumans
0

Nie jest to bezpośrednia odpowiedź na pytanie, ale uważam, że ten kod pomógł mi stworzyć dykty, które ładnie zapisują w poprawnej odpowiedzi. Dokonane konwersje typów są wymagane, jeśli te dane zostaną wyeksportowane do json.

Mam nadzieję, że to pomoże:

  #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
źródło