Reputation: 980
I'm trying to perform .is_valid()
after a POST request with my form.
form = DrinkForm(request.POST)
Like this, the "problem" is that this form has other parameters.
forms.py:
class DrinkForm(forms.Form):
def __init__(self, language, account_id, configurations, *args, **kwargs):
super(DrinkForm, self).__init__(*args, **kwargs)
translation.activate(language)
With this, I don't know how to make my form bound (and I can't find any guide or example about this case).
When I print my form called in view with its regular parameters it's everything ok, but if I add request.POST
I get nothing.
form_ok = DrinkForm('english', request.session['account_id'], configurations) # OK
form_not_ok = DrinkForm(request.POST) # Needs parameters
form_how_to = DrinkForm('english', request.session['account_id'], configurations, request.POST) # How to?
EDIT: added form and view codes
def create_drink(request):
if request.method == 'POST':
c = {}
c.update(csrf(request))
data = DrinkForm.build_create_data(request.POST)
try: # Tries to create the new drink
account = Account.objects.get(id=request.session['account_id'])
drinks_conf = DrinksConf.objects.get(account_id=request.session['account_id'])
form = DrinkForm(get_language(request), request.session['account_id'], drinks_conf, request.POST)
print(form) # Nothing is printed!
if form.is_valid():
print('valid?') # Not printed!
with transaction.atomic():
stock = DrinkStock.objects.create(account=account, stock=0)
Drink.objects.create(account=account, name=data['name'], cost=data['cost'], stock=stock,
stock_by=data['stock_by'])
return JsonResponse(DRINK_CREATE_SUCCESS)
else:
print('oh no not valid') # Neither printed!! What the..?
return JsonResponse(form_error_response(form.errors))
except: # Unknown exception
return JsonResponse(UNKNOWN_EXCEPTION)
forms.py:
class DrinkForm(forms.Form):
def __init__(self, language, account_id, drinks_conf, *args, **kwargs):
super(DrinkForm, self).__init__(*args, **kwargs)
translation.activate(language)
self.account_id = account_id # will be used in the future
self.drinks_conf = drinks_conf
options = (
(1, translation.gettext('Units')),
(3, translation.gettext('Litters'))
)
self.fields['name'] = forms.CharField(
max_length=100,
required=True,
label=translation.gettext('Name'),
widget=forms.TextInput(attrs={'class': 'form-control dynamic_object_submit'})
)
self.fields['cost'] = forms.DecimalField(
max_digits=14,
decimal_places=2,
required=True,
label=translation.gettext('Cost'),
widget=forms.NumberInput(attrs={'class': 'form-control dynamic_object_submit'})
)
self.fields['stock_by'] = forms.ChoiceField(
required=True,
label=translation.gettext('Stock/cost by'),
choices=options,
widget=forms.Select(attrs={'class': 'form-control dynamic_object_submit'})
)
def clean_cost(self):
if self.drinks_conf.cost_control is True:
data = self.cleaned_data['cost']
if data < 0:
raise forms.ValidationError(translation.gettext("Cost can't be negative"))
@staticmethod
def build_create_data(querydict):
return {
'name': querydict.get('name', None),
'cost': querydict.get('cost', None),
'stock_by': querydict.get('stock_by', None),
}
Upvotes: 0
Views: 183
Reputation: 32294
You can use gettext_lazy
on your field labels to provide translation at request time. Now you don't need to pass the language into your initialization method and the post data should bind correctly since you are not dynamically adding fields
from django.utils.translation import gettext_lazy as _
class DrinkForm(forms.Form):
name = forms.CharField(
max_length=100,
required=True,
label=_('Name'),
widget=forms.TextInput(attrs={'class': 'form-control dynamic_object_submit'})
)
cost = forms.DecimalField(
max_digits=14,
decimal_places=2,
required=True,
label=_('Cost'),
widget=forms.NumberInput(attrs={'class': 'form-control dynamic_object_submit'})
)
stock_by = forms.ChoiceField(
required=True,
label=_('Stock/cost by'),
choices=(
(1, _('Units')),
(3, _('Litters'))
),
widget=forms.Select(attrs={'class': 'form-control dynamic_object_submit'})
)
Upvotes: 1