2

I have this code which generates slug for django models. I have a different model field which is passed to function for generating it from (for example- name, title)

I marked variable name by naming it HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION

How do I pass this "title", "name" fields that so this function will work for any field name I pass it to.

# utils.py

DONT_USE = ['create']

def random_string_generator(
        size=2, chars=string.ascii_lowercase + string.digits
):
    return ''.join(random.choice(chars) for _ in range(size))


def unique_slug_generator(instance, HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION, new_slug=None):
    if new_slug is not None:
        slug = new_slug
    else:
        slug = slugify(instance.HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION)

    Klass = instance.__class__
    qs_exists = Klass.objects.filter(slug=slug).exists()
    if qs_exists:
        new_slug = f"{slug}-{random_string_generator(size=4)}"
        return unique_slug_generator(instance, HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION, new_slug=new_slug)
    return slug

I will use that function here

# models.py

class Category(models.Model):
    name = models.CharField(max_length=64)
    slug = models.SlugField(unique=True, blank=True)

class Event(models.Model):
    title = models.CharField(max_length=128)
    slug = models.SlugField(unique=True, blank=True)

def event_slug_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(
               instance, HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION="title"
        )


def category_slug_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(
               instance, HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION="name"
        )

2 Answers 2

2

Instead of passing the field name to the function, use the actual value you want to slugify as you are using that value for creating slug and not as the database lookup field.

def unique_slug_generator(instance, VALUE_YOU_WANT_TO_SLUGIFY, new_slug=None):
    if new_slug is not None:
        slug = new_slug
    else:
        slug = slugify(VALUE_YOU_WANT_TO_SLUGIFY)

    Klass = instance.__class__
    qs_exists = Klass.objects.filter(slug=slug).exists()
    if qs_exists:
        new_slug = f"{slug}-{random_string_generator(size=4)}"
        return unique_slug_generator(instance, VALUE_YOU_WANT_TO_SLUGIFY, new_slug=new_slug)
    return slug

call that function as:

def event_slug_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(
               instance, instance.title
        )


def category_slug_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(
               instance, instance.name
        )
Sign up to request clarification or add additional context in comments.

Comments

1

You can use getattr method to get instance's attribute by string:

def unique_slug_generator(instance, HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION, new_slug=None):
    if new_slug is not None:
        slug = new_slug
    else:
        slug = slugify(getattr(instance, HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.