user9252255
user9252255

Reputation:

Django: Filter & function

I have currently these to utils functions. The only difference between unique_account_link_generator and unique_order_id is what they filter within qs_exists. It's either .filter(slug=new_id) or .filter(order_id=new_id)

I now wonder is there a way to combine them and then being able to define the filter method when I call the function: unique_id_generator(instance, _filter = "order_id")

import random
import string

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

def unique_account_link_generator(instance):
    """
    1. Generates random string
    2. Check if string unique in database
    3. If already exists, generate new string
    """

    new_id = random_string_generator()

    myClass = instance.__class__
    qs_exists = myClass.objects.filter(slug=new_id).exists()
    if qs_exists:
        return unique_account_link_generator(instance)
    return new_id

# How to send field_name via function?
def unique_id_generator(instance):
    """
    1. Generates random string
    2. Check if string unique in database
    3. If already exists, generate new string
    """

    new_id = random_string_generator()

    myClass = instance.__class__
    qs_exists = myClass.objects.filter(order_id=new_id).exists()
    if qs_exists:
        return unique_id_generator(instance)
    return new_id

Upvotes: 1

Views: 212

Answers (2)

Nepo Znat
Nepo Znat

Reputation: 3290

I want to give you an answer to your question in the comments. Since the comment section doesn't allow much text I would like to attach this as an addition to the accepted answer.

It's actually correct that **{_filter:new_id} will unpack what's inside the _filter parameter

If you call the function with (instance, _filter="order_id")

this part **{_filter:new_id} will look like this **{"order_id":"randomGeneratedCode123"}

Now you have a dictionary with the key "order_id" and the value "randomGeneratedCode123"

You goal is to transform the key "order_id" to a parameter name and the value of the "order_id" key to the value of the parameter order_id

order_id = "randomGeneratedCode123"

As you already said you can unpack a dictionary with the double stars **

After unpacking it, the keys in the dictionary will be your parameter names and the values of the keys the parameter values

Here is a small example for better understanding:

Let's say you have a dictionary and a function

dict = {'a': 1, 'b': 2}

def example(a, b):
    print("Variable a is {}, b is {}".format(a, b))

example(**dict)

**dict is converted to: a = 1, b = 2 so the function will be called with

example(a = 1, b = 2)

It's important that the keys in your dictionary have the same name as your function parameter names

So this wouldn't work:

dict = {'a': 1, 'c': 2}
example(**dict)

because it's "translated " as

example(a = 1, c = 2)

and the function doesn't have a parameter with the name c

Upvotes: 0

albar
albar

Reputation: 3100

Not sure I understood the question, as the answer is very simple:

def unique_id_generator(instance, _filter="order_id"):
    new_id = random_string_generator()

    myClass = instance.__class__
    qs_exists = myClass.objects.filter(**{_filter:new_id}).exists()
    if qs_exists:
        return unique_id_generator(instance, _filter)
    return new_id

Upvotes: 1

Related Questions