So basic task is: add the template name and text to the choices
in the ChoiceField
with Selector
widget to the form using the data from dB linked to the authenticated User only. Template
is a model linked to user as a ForeignKey
.
I'd like to access the request data(user) via the Form class linked to the connected view as django.views.generic.View
class.
I've checked similar questions here: Curious about get_form_kwargs in FormView
and here: Sending request.user object to ModelForm from class based generic view in Django
and here: Django: Accessing request in forms.py clean function
However they don't touch base with non-FormView
classes. And as it's fairly old solutions, I was curious if there's more likely approach to reach request
from forms.Form
class.
Here's my code:
views.py
class InformFill(View):
form_class = InformForm
temlate_name = 'distrib_db/inform_fill.html'
def get(self, request):
if request.user.is_authenticated():
form = self.form_class(None)
return render(request, self.temlate_name, context={'form': form})
else:
return redirect('distrib_db:login')
def post(self, request):
if request.user.is_authenticated():
form = self.form_class(request.POST)
if form.is_valid():
inform = Inform(flt_numbr=form.cleaned_data['flight_number'], date=form.cleaned_data['date'],
template=form.cleaned_data['text'], user=request.user)
inform.save()
date = form.cleaned_data['date']
flt_numbr = form.cleaned_data['flight_number']
try:
emails, contacts = get_mail_cnt(date, flt_numbr)
# inform = get_object_or_404(Inform, pk=request['pk'])
paxdata = PaxData(inform=inform, emails=' '.join(emails), contacts=' '.join(contacts))
paxdata.save()
return redirect('/inform/{0}/'.format(inform.pk))
# 'distrib_db:detail', context={'pk': inform.id}
except Exception as e:
return render(request, 'distrib_db/sample.html',
context={'date': date, 'flight_number': flt_numbr, 'error': e})
# return render(request, 'distrib_db/sample.html', context={'date': date, 'flt_numbr': flt_numbr})
return render(request, self.temlate_name, context={'form': form})
else:
return redirect('distrib_db:login')
forms.py
class InformForm(forms.Form):
flight_number = forms.CharField(5, widget=forms.TextInput())
date = forms.DateField(widget=forms.DateInput(attrs={'class': 'datepicker'}))
template = forms.ChoiceField(choices=templates, widget=forms.Select(attrs={'id': 'select_box',
'onchange': 'javascript:changer();'}))
text = forms.CharField(widget=forms.Textarea(attrs={'id': 'txt_box', 'class': 'latin',
'maxlength': "160", 'onchange': 'javascript:validateTextArea();'}))
Generally speaking i'd like to achieve smth like this:
`class InformForm(forms.Form):
def get_template_choices(self):
templates = self.request.user.template_set.all()
choices = []
for t in templates:
choices.append((t.text, t.name))
return choices
flight_number = forms.CharField(5, widget=forms.TextInput())
date = forms.DateField(widget=forms.DateInput(attrs={'class':
'datepicker'}))
template = forms.ChoiceField(choices=get_template_choices(),
widget=forms.Select(attrs=
{'id': 'select_box',
'onchange': 'javascript:changer();'}))
text = forms.CharField(widget=forms.Textarea(attrs={'id': 'txt_box',
'class': 'latin',
'maxlength': "160",
'onchange': 'javascript:validateTextArea();'}))`
I'd appreciate any approach, mb I lack knowledge and asking newbie questions, sorry about it.
I just wanna get the python-way
solution rather then build some js/jinja
walk-arounds.
Thank you for your time!
#After @Danielius comments, I've made some adjustments:
`class InformForm(forms.Form):
def __init__(self, user=None, *args, **kwargs):
if user:
self.fields['template'] = forms.ChoiceField(choices=tuple([(template.text, template.name) for template in user.template_set.all()]),
widget=forms.Select(attrs={'id': 'select_box', 'onchange': 'javascript:changer();'}))
flight_number = forms.CharField(5, widget=forms.TextInput())
date = forms.DateField(widget=forms.DateInput(attrs={'class': 'datepicker'}))
# template = forms.ChoiceField(choices=templates, widget=forms.Select(attrs={'id': 'select_box',
# 'onchange': 'javascript:changer();'}))
text = forms.CharField(widget=forms.Textarea(attrs={'id': 'txt_box', 'class': 'latin',
'maxlength': "160", 'onchange': 'javascript:validateTextArea();'}))`
Got an error AttributeError: 'InformForm' object has no attribute 'fields'
You can pass request to your form by changing your __init__
method like this :
class InformForm(forms.Form):
...
def __init__(self, user=None,*args, **kwargs):
super(InformForm, self).__init__(**kwargs)
if user:
self.fields['somefield'] = forms.ChoiceField()
self.fields['somefield'].widget = forms.Select()
self.fields['somefield'].queryset = Someobject.objects.filter(User=user)
...
If the User is linked to other object in db by Foreign key, then you will get all the values of other object as select items.
Also , when creating form you could pass user like this :
form= InformForm(user=request.user,data=request.POST)