добавление ** kwarg к классу - PullRequest
3 голосов
/ 12 июня 2009
class StatusForm(ModelForm):

    bases = forms.ModelMultipleChoiceField(
            queryset=Base.objects.all(),  #this should get overwritten
            widget=forms.SelectMultiple,
        )

    class Meta:
        model = HiringStatus
        exclude = ('company', 'date')

    def __init__(self, *args, **kwargs):
        super(StatusForm, self).__init__(*args, **kwargs)
        if kwargs.has_key('bases_queryset'):
            self.fields['bases'].queryset = kwargs['bases_queryset']

Я хочу добавить в эту форму опцию, которая позволит мне создать такую ​​форму:

form = StatusForm(bases_queryset=Base.objects.filter([...])

Но мне как-то нужно «добавить» этот аргумент ключевого слова в класс, чтобы он был распознан. Они так, как сейчас, я просто получаю эту ошибку:

__init__() got an unexpected keyword argument 'bases_queryset'

Ответы [ 2 ]

11 голосов
/ 12 июня 2009

Как указывает @Keeper, вы не должны передавать свои «новые» аргументы ключевого слова суперклассу. Лучше всего, прежде чем звонить в Super's __init__:

bqs = kwargs.pop('bases_queryset', None)

и после этого __init__ вызова отметьте if bqs is not None: вместо has_key (и, конечно, используйте bqs вместо kwargs['bases_queryset']).

Интересный альтернативный подход заключается в создании функции «селективного вызова» высшего порядка. Это немного беспорядок, если у вас есть как позиционные, так и именованные аргументы (это всегда немного запутано в метапрограмме ;-), поэтому для простоты изложения предположим, что функция, которую вы хотите выборочно вызывать, имеет только "нормальный" msgstr "именованные аргументы (т.е. не **k). Сейчас:

import inspect

def selective_call(func, **kwargs):
    names, _, _, _ = inspect.getargspec(func)
    usable_kwargs = dict((k,kwargs[k]) for k in names if k in kwargs)
    return func(**usable_kwargs)

с этим подходом, в вашем __init__ вместо прямого вызова супер 101 *, вы бы позвонили selective_call(super_init, **kwargs) и пусть эта функция более высокого порядка выполнит необходимую «обрезку». (Конечно, вам потребуется сделать его более беспорядочным для обработки как позиционных, так и именованных аргументов, ну, хорошо ...! -)

11 голосов
/ 12 июня 2009

Это потому, что вы распаковываете kwargs в конструктор super. Попробуйте поставить это перед вызовом super:

if kwargs.has_key('bases_queryset'):
    bases_queryset = kwargs['bases_queryset']
    del kwargs['bases_queryset']

но это не идеальное решение ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...