310 votes

Comment utiliser correctement get_or_create ?

J'essaie d'utiliser get_or_create pour certains champs de mes formulaires, mais je reçois une erreur 500 lorsque j'essaie de le faire.

L'une des lignes ressemble à ceci :

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

L'erreur que je reçois pour le code ci-dessus est :

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

510voto

Bryan Rehbein Points 3947

Extrait de la documentation obtenir_ou_créer :

# 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

Explication : Les champs à évaluer pour la similarité doivent être mentionnés à l'extérieur de la zone d'évaluation. defaults . Le reste des champs doit être inclus dans defaults . En cas d'événement CREATE, tous les champs sont pris en compte.

Il semble que vous deviez retourner dans un tuple, au lieu d'une seule variable, faites comme ceci :

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

9 votes

Pour info, created est un booléen. Vrai s'il a été créé, Faux s'il a été récupéré.

5 votes

Un complément save() est redondant ?

2 votes

@zypro C'est comme create() créer un objet et le sauvegarder en une seule étape, sans qu'il soit nécessaire d'avoir recours à des logiciels de gestion de l'information. save()

41voto

Tobu Points 10101

get_or_create renvoie un tuple.

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

17 votes

Ou, si vous ne vous souciez pas de l'indicateur booléen : customer.source = Source.objects.get_or_create(name="Website")[0]

25 votes

@mipadi Je préférerais customer.source, _ = Source.objects.get_or_create(name="Website") car cela rend plus évident le fait qu'un tuple a été retourné, ce qui permet d'éviter de futurs bogues.

33voto

Tushar.PUCSD Points 343

get_or_create() renvoie un tuple :

customer.source, created  = Source.objects.get_or_create(name="Website")
  • created a une valeur booléenne, est créé ou non.

  • customer.source a un objet de get_or_create() méthode.

22voto

jbondia Points 173

Suite à la réponse de @Tobu et au commentaire de @mipadi, d'une manière plus pythonique, si je ne suis pas intéressé par le drapeau créé, j'utiliserais :

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

7voto

wlashell Points 780

Le problème que vous rencontrez est une fonctionnalité documentée de l'outil de gestion de l'information. get_or_create .

Lorsque vous utilisez des arguments de mots-clés autres que "defaults", la valeur de retour de la fonction get_or_create est une instance. C'est pourquoi il vous montre les parenthèses dans la valeur de retour.

vous pourriez utiliser customer.source = Source.objects.get_or_create(name="Website")[0] pour obtenir la valeur correcte.

Voici un lien pour la documentation : http://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create-kwargs

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X