0

Here's my code:

def update_tags_with_value(tags, many_to_many_class):
    if tags:
        many_to_many_class.objects.filter(
            personne=self.instance,

            date_v_fin=None
        ).update(date_v_fin=django_datetime.now())
        for idx_tag_with_value in tags:
            pl = many_to_many_class.objects.create(
                personne=self.instance,
                langue=TagWithValue.objects.get(
                    pk=idx_tag_with_value
                )
            )
            pl.save()

update_tags_with_value(self.cleaned_data.get('known_languages'),
                       PersonneLangue)
update_tags_with_value(self.cleaned_data.get('types_permis'),
                       PersonneTypesPermis)

So I found out I can easily pass a class as a parameter. But the last problem is about the named argument. If you watch my code, I do a langue=TagWithValue..[blabla]. The problem is that it's a "named" parameter, and I'd like to be able to pass it like that:

update_tags_with_value(self.cleaned_data.get('known_languages'),
                       PersonneLangue, 'langue')
update_tags_with_value(self.cleaned_data.get('types_permis'),
                       PersonneTypesPermis, 'permis')

And then to call it somehow like that (it doesn't work yet):

    def update_tags_with_value(tags, many_to_many_class, champ):
        if tags:
            many_to_many_class.objects.filter(
                personne=self.instance,

                date_v_fin=None
            ).update(date_v_fin=django_datetime.now())
            for idx_tag_with_value in tags:
                pl = many_to_many_class.objects.create(
                    personne=self.instance,
                    champ=TagWithValue.objects.get(
                        pk=idx_tag_with_value
                    )
                )
                pl.save()

For now I get this error:

'champ' is an invalid keyword argument for this function

To be more precise, I need to call many_to_many_class.objects.create() one time with known_languages=blabla and another time with types_permis=blabla which, in other words, should call once many_to_many_class.objects.create(known_languages=blabla) and many_to_many_class.objects.create(types_permis=blabla) and I would like to know if there's a way to precise only the name of the parameter, not blabla

How to solve this?

Olivier Pons
  • 15,363
  • 26
  • 117
  • 213
  • 1
    I don't 100% understand what you want, but [named argument unpacking](http://stackoverflow.com/questions/36901/what-does-double-star-and-star-do-for-python-parameters) may be useful to you. You can create a dictionary and pass it to a function as if it was a collection of keyword args. – Kevin Dec 28 '15 at 18:40

2 Answers2

0

Seems like normal keyword unpacking would work . . .

kwargs = {champ: TagWithValue.objects.get(
                     pk=idx_tag_with_value)}
pl = many_to_many_class.objects.create(
                    personne=self.instance,
                    **kwargs)

Of course, now champ might not be the best name for the function parameter, but hopefully you get the idea.

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • My problem is that, strictly speaking, I need to call `many_to_many_class.objects.create()` one time with `known_languages=blabla` and another time with `types_permis=blabla` which, in other words, should call once `many_to_many_class.objects.create(known_languages=blabla)` and `many_to_many_class.objects.create(types_permis=blabla)` and I would like to know if there's a way to precise *only the name of the parameter*, **not** `blabla` – Olivier Pons Dec 28 '15 at 19:29
0

Here's my working solution, I don't know if it's the best "pythonic" way but it works like a charm:

def update_tags_with_value(tags, many_to_many_class, champ):
    if tags:
        many_to_many_class.objects.filter(
            personne=self.instance,
            date_v_fin=None
        ).update(date_v_fin=django_datetime.now())
        for idx_tag_with_value in tags:
            args = {
                'personne': self.instance,
                champ: TagWithValue.objects.get(
                    pk=idx_tag_with_value
                )}
            pl = many_to_many_class.objects.create(**args)
            pl.save()

update_tags_with_value(self.cleaned_data.get('known_languages'),
                       PersonneLangue, 'langue')
update_tags_with_value(self.cleaned_data.get('types_permis'),
                       PersonneTypePermis, 'type_permis')
update_tags_with_value(self.cleaned_data.get('diplomes'),
                       PersonneDiplome, 'diplome')
update_tags_with_value(self.cleaned_data.get('centres_dinteret'),
                       PersonneCentreDInteret, 'centre_dinteret')
update_tags_with_value(self.cleaned_data.get('hobbies'),
                       PersonneHobby, 'hobby')
Olivier Pons
  • 15,363
  • 26
  • 117
  • 213