2

J'ai créé une fonction qui se connecte au signal 'pre_save' d'un modèle. A l'intérieur de la fonction que je suis en train de vérifier si le modèle de l'instance de pk existe déjà dans la table:Django Model.object.get pre_save Fonction Weirdness

sender.objects.get(pk=instance._get_pk_val()) 

La première instance du modèle soulève une erreur. J'attrape l'erreur et génère un champ de slug à partir du titre. Dans un deuxième cas, il ne lance pas l'erreur. J'ai vérifié la valeur sur les deux instances instance._get_pk_val() et ils sont les mêmes: Aucun

Alors:

# This one raises an error in the sluggit function 
instance1 = Model(title="title 1") 
instance1.save() 

# This one doesn't raise an error 
instance2 = Model(title="title 2") 
instance2.save() 

Ceci est mon 3ème jour de déconner avec python et django. Donc je suis désolé si c'est quelque chose de nouveau que je ne vois pas.

Edit:

Le modèle:

class Test(models.Model): 
    title = models.CharField(max_length=128) 
    slug = models.SlugField(max_length=128) 
    slug.prepopulate_from=('title',) 

signals.pre_save.connect(package.sluggit, sender=Test) 

Les bases de fonction:

def sluggit(sender, instance, signal, *args, **kwargs): 
    try: 
     sender.objects.get(pk=instance._get_pk_val()) 
    except: 
     # Generate Slug Code 

@ S.Lot m'a dit de passer outre la méthode save() dans les commentaires. Je vais devoir essayer ça. J'aimerais quand même savoir pourquoi le second appel à model.objects.get() ne déclenche pas d'erreur avec cette méthode.

Édition 2 Merci @ S.Lot. Le remplacement de la méthode save fonctionne parfaitement. Toujours curieux de connaître la méthode du signal. Hmm, bizarre.

Edit 3 Après avoir joué un peu plus, je trouve que l'utilisation instance.objects.get() au lieu de sender.objects.get() fonctionne:

def sluggit(sender, instance, signal, *args, **kwargs): 
    try: 
     sender.objects.get(pk=instance._get_pk_val()) 
    except: 
     # Generate Slug Code 

doit être:

def sluggit(sender, instance, signal, *args, **kwargs): 
    try: 
     instance.objects.get(pk=instance._get_pk_val()) 
    except: 
     # Generate Slug Code 

Un bug? Pour une raison quelconque, je pensais que sender.objects.get() serait le même que Test.objects.get().

+0

Qu'essayez-vous vraiment d'accomplir? Pourquoi jouez-vous avec la mise à jour par rapport au comportement d'insertion de Django? Il y a rarement une raison de jouer avec pre_save. Qu'essayez-vous vraiment de faire? –

+1

J'essaie de générer un SlugField à partir du titre.S'il s'agit d'une mise à jour, je ne veux pas qu'elle génère un nouveau slug. – Matt

+0

@Matt: S'il vous plaît mettre à jour votre question avec de nouveaux faits. Vous n'avez pas besoin de jouer avec pre_save pour cela. Remplacer save(). –

Répondre

1

S.Lott est correct ... utilisez save(), comme vous avez déjà reconnu que vous avez commencé à le faire. En ce qui concerne la question de signal, je ne peux honnêtement voir rien de mal avec votre code. Je l'ai même géré localement avec succès. Êtes-vous sûr que vous le représentez correctement dans la question? Ou que instance2 n'est pas déjà un objet de base de données existant (peut-être un goof dans votre code de test)?

+0

J'ai essayé de tester ceci dans le shell manage.py. C'est exactement ce que j'ai essayé: >>> de testing.models import Test >>> t1 = Test (title = "un titre de test") >>> t1.save() >>> t1.slug 'un test title' >>> t2 = test (title = "un titre de test") >>> t2.save() >>> t2.slug '' – Matt

+0

Wow, qui est laid. Hmm, je vais regarder par-dessus mon code et voir si j'ai fait une erreur. – Matt

+0

J'ai juste remarqué "prepopulate_from" ... quelle version de django utilisez-vous? A défaut de ... quel est le code dans "Generate Slug Code"? –

0

Merci d'avoir posté ce message. Les meilleurs résultats google (au moment où je poste ceci) sont un peu démodés et montrent l'ancienne façon de connecter les signaux (qui a été récemment réécrite, apparemment). Vos modifications, avec les extraits de code corrigés, m'ont montré comment cela se fait.

Je souhaite que plus d'affiches aient modifié leurs commentaires pour y remédier. Merci. :-)

Questions connexes