Modo corretto di usare get_or_create?


203

Sto cercando di utilizzare get_or_create per alcuni campi nei miei moduli, ma quando provo a farlo ottengo un errore 500.

Una delle linee appare così:

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

L'errore che ottengo per il codice sopra è:

Cannot assign "(<Source: Website>, False)": "Customer.source" 
   must be a "Source" instance.

Risposte:


353

Dalla documentazione 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

Spiegazione: I campi da valutare per la somiglianza devono essere menzionati all'esterno defaults. Il resto dei campi deve essere incluso indefaults . Nel caso in cui si verifichi l'evento CREATE, vengono presi in considerazione tutti i campi.

Sembra che tu debba tornare in una tupla, invece di una singola variabile, in questo modo:

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

3
La FYI creata è un booleano. Vero se creato, Falso se viene recuperato
Josh

3
Un ulteriore save()è ridondante?
zypro,

@zypro È come create(), creare un oggetto e salvarlo tutto in un solo passaggio e non ne ha bisognosave()
Amin Mir

32

get_or_create restituisce una tupla.

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

16
Oppure, se non ti interessa la bandiera booleana:customer.source = Source.objects.get_or_create(name="Website")[0]
mipadi,

7
@mipadi Preferirei customer.source, _ = Source.objects.get_or_create(name="Website"), poiché rende più ovvio il fatto che una tupla è stata restituita, aiutando a evitare futuri bug.
Solomon Ucko

15

get_or_create() restituisce una tupla:

customer.source, created  = Source.objects.get_or_create(name="Website")
  • created ha un valore booleano, viene creato o no.

  • customer.source ha un oggetto di get_or_create()metodo.


12

Dopo la risposta di @Tobu e il commento di @mipadi, in un modo più pitonico, se non fosse interessato al flag creato, userei:

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

4

Il problema riscontrato è una funzionalità documentata di get_or_create.

Quando si utilizzano argomenti di parole chiave diversi da "valori predefiniti", il valore restituito di get_or_createè un'istanza. Ecco perché ti mostra le parentesi nel valore di ritorno.

potresti usare customer.source = Source.objects.get_or_create(name="Website")[0]per ottenere il valore corretto.

Ecco un link per la documentazione: http://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create-kwargs

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.