Передать поле экземпляра для функции в качестве параметра - PullRequest
1 голос
/ 04 апреля 2020

У меня есть этот код, который генерирует слаг для django моделей. У меня есть другое поле модели, которое передается в функцию для его генерации (например, name, title)

Я пометил имя переменной, назвав ее HELP_HERE_INSTANCE_FIELD_PASS_TO_FUNCTION

How передать эти поля "title", "name", чтобы эта функция работала для любого имени поля, которому я ее передаю.

# 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

Я буду использовать эту функцию здесь

# 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 ]

2 голосов
/ 04 апреля 2020

Вместо того, чтобы передавать имя поля в функцию, используйте фактическое значение, которое вы хотите убить, так как вы используете это значение для создания слага, а не как поле поиска в базе данных.

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

    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, <b>VALUE_YOU_WANT_TO_SLUGIFY</b>, new_slug=new_slug)
    return slug

вызовите эту функцию как:

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


def category_slug_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug:
        instance.slug = unique_slug_generator(
               instance, <b>instance.name</b>
        )
1 голос
/ 04 апреля 2020

Вы можете использовать метод getattr, чтобы получить атрибут экземпляра по строке:

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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...