Reputation: 141
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"
)
Upvotes: 2
Views: 717
Reputation: 2342
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
)
Upvotes: 2
Reputation: 47354
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))
Upvotes: 1