Reputation: 15796
I have this code:
hobbies2 = form.cleaned_data.pop('hobbies2')
PersonneHobby.objects.filter(personne=obj).delete()
for pk_str in hobbies2:
try:
hobby = TagTraduit.objects.get(pk=int(pk_str))
p = PersonneHobby.objects.create(personne=obj,
hobby=hobby)
p.save()
except ValueError:
break # hack in the POST
except LookupError:
break # hack in the POST
I will have the same code for 4 different fields, exemple with programme
:
programmes2 = form.cleaned_data.pop('programmes2')
PersonneProgramme.objects.filter(personne=obj).delete()
for pk_str in programmes2:
try:
programme2 = TagTraduit.objects.get(pk=int(pk_str))
p = PersonneProgramme.objects.create(personne=obj,
programme=programme2)
p.save()
except ValueError:
break # hack = tout stopper
except LookupError:
break # hack = tout stopper
Exactly the same code, only name of the field change. So I'd like to make a generic function and call it like this:
def update_field(post_field, class_field, **kwargs):
try:
values = form.cleaned_data.pop(post_field)
class_field.objects.filter(personne=obj).delete()
for pk_str in values:
try:
v = TagTraduit.objects.get(pk=int(pk_str))
p = class_field.objects.create(**{'personne': obj,
field_name: v})
p.save()
except ValueError:
break # hack = tout stopper
except LookupError:
break # hack = tout stopper
except KeyError:
pass
update_field('programmes2', PersonneProgramme, 'programme')
update_field('hobbies2', PersonneHobby, 'hobby')
My main problem is the last parameter, which is the name of the field to use when creating the record in the database.
How to do it?
Upvotes: 4
Views: 94
Reputation: 152725
You could do it with an arbitary number of keyword-arguments (**
) and insert calculated additional parameters inside the function:
def update_field(field, update_this, **kwargs):
...
kwargs[update_this] = TagTraduit.objects.get(pk=int(pk_str))
p = field.objects.create(**kwargs)
...
this allows you to call it like that:
update_field(PersonneHobby, 'hobby', personne=obj)
update_field(PersonneProgramme, 'programme', personne=obj)
Upvotes: 4
Reputation: 3415
I will go with what @MSeifert said. If you want whatever you have written to work, I mean with positional arguments alone.
def f(a,b,c):
a.func(b=b, c=c) # this is perfectly legal
But the better way to go about it is,
def f(a, **kwargs):
a.func(**kwargs) # kwargs is passed as a dict. **kwargs is
# unpacking it into key1=val1, key2=val2, ...
Upvotes: 1
Reputation: 59315
You can do this:
def update_field(..., field_name):
...
tag = TagTraduit.objects.get(pk=int(pk_str))
p = PersonneProgramme.objects.create(**{'personne': obj, field_name: tag})
Upvotes: 3