jeremy_lord
jeremy_lord

Reputation: 469

Persistent slug in Django

In my Django web application, each user has a randomly generated token generated for purposes beyond the scope of this question.

This is the relevant Profile model

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,max_length=30)
    verified_account = models.BooleanField(default=False)
    verify_token = models.SlugField(max_length=15, blank=True, null=True, unique=True)

    def __str__(self):
       return self.user.username

    def get_absolute_url(self):
        return reverse('user:profile', kwargs={'pk': self.pk})

    def generate_token(self): #important
        from django.utils.crypto import get_random_string
        self.verify_token = get_random_string(length=15)
        return self.verify_token

    def save(self, *args, **kwargs): # also important
        self.slug = slugify(self.user.username)
        self.generate_token() # issue is here
        super().save(*args, **kwargs)

So basically, whenever a Profile object is created (on the creation of the User model), a token is randomly generated. However, whenever the Profile model is updated, so is the verify_token. Below is the code for my @receiver that handles user creation

@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    else:
        instance.profile.save()

I have tried to insert the following code below the Profile.objects.create(user=instance) line in order to try and get it to only generate the token when the Profile is created

Profile.objects.filter(user=instance).generate_token()

But this gives me the following error

'QuerySet' object has no attribute 'generate_token'

What is the best way to ensure that the slug is not changed after every update of it's Profile model?

Thank you in advance for any solutions

Upvotes: 0

Views: 36

Answers (2)

jeremy_lord
jeremy_lord

Reputation: 469

Thank you to Işık Kaplan for providing the basis to my solution.

What I ended up doing was simply add a conditional to the save() function - if self.verify_token is None:

Thank you again!

Upvotes: 0

Işık Kaplan
Işık Kaplan

Reputation: 2982

Just add a slug field as read only? Also, the reason you get an error is because .filter() gives you a query set, not an instance.

Profile.objects.filter(user=instance).get().generate_token()

should work

Upvotes: 1

Related Questions