Prawidłowy sposób użycia get_or_create?

203

Próbuję użyć get_or_create dla niektórych pól w moich formularzach, ale otrzymuję błąd 500, gdy próbuję to zrobić.

Jedna z linii wygląda następująco:

customer.source = Source.objects.get_or_create(name="Website")

Występuje błąd dla powyższego kodu:

Cannot assign "(<Source: Website>, False)": "Customer.source" 
   must be a "Source" instance.
Stephen
źródło

Odpowiedzi:

353

Z dokumentacji get_or_create :

# get_or_create() a person with similar first names.

p, created = Person.objects.get_or_create(
    first_name='John',
    last_name='Lennon',
    defaults={'birthday': date(1940, 10, 9)},
)

# get_or_create() didn't have to create an object.
>>> created
False

Objaśnienie: Pola, które należy ocenić pod kątem podobieństwa, należy wymienić na zewnątrz defaults. Pozostałe pola muszą być uwzględnione w defaults. W przypadku wystąpienia zdarzenia UTWÓRZ uwzględniane są wszystkie pola.

Wygląda na to, że musisz wrócić do krotki zamiast jednej zmiennej, wykonaj następujące czynności:

customer.source,created = Source.objects.get_or_create(name="Website")
Bryan Rehbein
źródło
3
Utworzona przez Ciebie informacja finansowa jest wartością logiczną. Prawda, jeśli zostanie utworzona, Fałsz, jeśli zostanie pobrany
Josh
3
Dodatkowa save()jest zbędna?
zypro
@zypro To jak create(), stwórz obiekt i zapisz go w jednym kroku i nie potrzebuje żadnegosave()
Amin Mir
32

get_or_create zwraca krotkę.

customer.source, created = Source.objects.get_or_create(name="Website")
Tobu
źródło
16
Lub, jeśli nie przejmujesz się flagą boolowską:customer.source = Source.objects.get_or_create(name="Website")[0]
mipadi
7
@mipadi Wolę customer.source, _ = Source.objects.get_or_create(name="Website"), ponieważ dzięki temu krotka została zwrócona bardziej oczywista, co pomaga uniknąć przyszłych błędów.
Solomon Ucko
15

get_or_create() zwraca krotkę:

customer.source, created  = Source.objects.get_or_create(name="Website")
  • created ma wartość logiczną, został utworzony lub nie.

  • customer.source ma obiekt get_or_create()metody.

Tushar.PUCSD
źródło
12

Po odpowiedzi na @Tobu i komentarzu @mipadi, w bardziej pythonowy sposób, jeśli nie jestem zainteresowany stworzoną flagą, użyłbym:

customer.source, _ = Source.objects.get_or_create(name="Website")
jbondia
źródło
4

Napotkany problem to udokumentowana funkcja get_or_create.

Gdy używasz argumentów słów kluczowych innych niż „defaults”, zwracaną wartością get_or_createjest instancja. Dlatego pokazuje ci parens w wartości zwracanej.

możesz użyć, customer.source = Source.objects.get_or_create(name="Website")[0]aby uzyskać poprawną wartość.

Oto link do dokumentacji: http://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create-kwargs

wlashell
źródło