Reputation:
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
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
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