Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Model.object.get pre_save Function Weirdness

I have made a function that connects to a models 'pre_save' signal. Inside the function I am trying to check if the model instance's pk already exists in the table with:

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

The first instance of the model raises an error. I catch the error and generate a slug field from the title. In a second instance, it doesn't throw the error. I checked the value of instance._get_pk_val() on both instances and they are the same: None

So:

# 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()

This is my 3rd day messing around with python and django. So I am sorry if it something newbish that I am not seeing.

Edit:

The Model:

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)

The Function Basics:

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

@S.Lot told me to override the save() method in the comments. I'll have to try that. I would still like to know why the second call to model.objects.get() isn't raising an error with this method.

Edit 2 Thank you @S.Lot. Overriding the save method works perfectly. Still curious about the signal method. Hmm, weird.

Edit 3 After playing around a little more, I found that using instance.objects.get() instead of sender.objects.get() works:

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

needs to be:

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

A bug? For some reason I thought sender.objects.get() would be the same as Test.objects.get().

like image 971
Matt Avatar asked Sep 19 '26 21:09

Matt


1 Answers

S.Lott is correct... use save(), as you've already acknowledged that you have started doing.

As for the signal question, I can honestly see nothing wrong with your code. I've even run it locally myself with success. Are you sure that you're representing it properly in the question? Or that instance2 isn't already an existing database object (perhaps a goof in your test code)?

like image 146
Jarret Hardie Avatar answered Sep 22 '26 10:09

Jarret Hardie