@Andrey_Dolg

Как переопределить initial data в django form?

Приветствую.
С формы в Django приходит токен который генерируется платежной системой. Я объявляю форму с одним скрытым полем, которое принимает токен. Js либа платежки создаёт свою форму и генерирует поля для ввода. При совпадении имен hidden input django и платёжной системы(получаем 2 hidden input), токен не приходит никуда и получаем ''Token'' : [" "," "]. При изменении имени поля в коде Django получаем токен по имени js формы "Token":["token"], "Djangoinput"[" "]. Суть проблемы в том что я не хочу менять views платформы, а ограничиться изменениями в файле forms.py для данной конкретной платежной системы.
Если кратко то? переопределить входящие в форму параметры, и записать в Djangoinput токен, который приходит в **kwargs.
Что приходит в **kwargs __init__ формы.
{'data':
<QueryDict: {'csrfmiddlewaretoken': ['****'],
 'Token': ['tokn_test_5ezewjccegvcnzm6exn'],
 'Source': [''],
 'Djangoinput': [''],
 'username': ['']}>
}


Кода формы:
class PaymentForm(forms.Form):

    Djangoinput = forms.CharField(widget=forms.HiddenInput, required=True)

    def __init__(self, payment_information, gateway_params, *args, **kwargs):
        token = None
        initial_arguments = kwargs.get('data', None)
        if initial_arguments:
            token = initial_arguments.get('Token', None)
            csrf = initial_arguments.get('csrfmiddlewaretoken', None)

            # Now update the form's initial values
            if token:
                data_test={}
                data_test['Djangoinput'] = [token,]
                data_test['csrfmiddlewaretoken'] = csrf
                kwargs.update({'data' : data_test})
        super(PaymentForm, self).__init__(*args, **kwargs)
        self.fields['Paymentforms'] = forms.CharField(
            widget=PayCheckoutWidget(
                payment_information=payment_information,
                gateway_params=gateway_params),
            required=False)

Валится в form.is_valid() требует ввода данных в hidden input.
Обход проблемы доступен путем удаление поля Django по id в js и это работает.
Однако, смотря на другие уже встроенные платежные системы вижу, что видимо библиотеки генерируют поля сами, но умеют определять уже созданное в форме поле(с правильным именем) и передавать в него данные, без генерации своего поля, что помогает им работать с этой Dajngo платформой. Вообщем хотелось бы иметь 2 hiddeninput с разными именами и возможностью передать токен в поле djangoinput в forms.py. Возможно туплю =)
Django 2.1.5
Python 3.6.6
  • Вопрос задан
  • 925 просмотров
Решения вопроса 1
@Andrey_Dolg Автор вопроса
Вообщем видимо ошибка исчезла. =)

Более читаемый код.
class PaymentForm(forms.Form):
    token = forms.CharField(widget=forms.HiddenInput, required=True)

    def __init__(self, payment_information, gateway_params, *args, **kwargs):
        initial_arguments = kwargs.get('data', None)
        if initial_arguments:
            token = initial_arguments.get('Token', None)
            csrf = initial_arguments.get('csrfmiddlewaretoken', None)
            if token:
                kwargs.update({'data':{'token':token, 'csrfmiddlewaretoken': csrf }})
        super(OmisePaymentForm, self).__init__(*args, **kwargs)


Так же валидно.
kwargs.update(data = {'token':token, 'csrfmiddlewaretoken': csrf })


И можно при вызове метод __init__ предка Form указать initial= {'token':token, 'csrfmiddlewaretoken': csrf } или data={...} однако перед этим почистить kwargs от таких имен. Что и написано в документации.
Как я понимаю за заполнение ответственен это фрагмент BaseForm:
def _clean_fields(self):
        for name, field in self.fields.items():
            # value_from_datadict() gets the data from the data dictionaries.
            # Each widget type knows how to retrieve its own data, because some
            # widgets split data over several HTML fields.
            if field.disabled:
                value = self.get_initial_for_field(field, name)
            else:
                value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы