JAEMYUN IS GRANDPA JAEMYUN IS GRANDPA - 2 months ago 6
Python Question

Django How I can pass request.user(current logged user) in forms when I use class based view?

I wanted to pass request.user to show current user in a form with ModelMultipleChoiceField. I could figure out my problem thanks to here http://stackoverflow.com/a/25184373/6568309. I fixed my code like below.

but I could get solution with only function based view. well, I kept using class based views because I could use generic views and it was recommended in first place. Is it way to pass request.user like below with class based view(to use FormView or ModelFormView)? Additionally, Is is normal to mix function based views and class based views to meet your need in Django?

thank you in advance.

forms.py

class CustomForm(forms.Form):
username = forms.CharField(initial='testname',max_length=150)
email = forms.EmailField()
phone_number = forms.CharField(max_length=15)
position = forms.CharField(max_length=15)
uperall = forms.ModelMultipleChoiceField(queryset=None)

def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super(CustomForm, self).__init__(*args, **kwargs)
self.fields['uperall'].queryset = User.objects.filter(username=user.username)


urls.py

urlpatterns = [
url(r'^$', UserList.as_view(), name='index'),
url(r'^create/$', UserCreate.as_view(), name='create'),
url(r'^test/$', TestView.as_view(), name='test'),
url(r'^test1/$', views.ftestview, name='test1'),
]


views.py

def ftestview(request):
if request.method == 'POST':

form = CustomForm(request.POST, user=request.user)

if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
phone_number = form.cleaned_data['phone_number']
position = form.cleaned_data['position']

with transaction.atomic():
user = User.objects.create(username=username,email=email)
userinfo = UserInfo.objects.create(user=user,phone=phone_number,position=position)
userinfo.save()
user.save()

return HttpResponseRedirect('/success')

else:
form = CustomForm(user=request.user)

return render(request, 'manager/alltoall.html', { 'form': form })


according to answer from levi thanksfully. I changed my code like below

views.py

class TestView(FormView):
form_class = CustomForm
template_name = 'manager/alltoall.html'

def get_form_kwargs(self):
user = self.request.user
form_kwargs = super(TestView, self).get_form_kwargs()
form_kwargs.update({'initial': {'uperall': User.objects.filter(username=user.username)}})
return form_kwargs

def form_valid(self, form):
username = form.cleaned_data['username']
email = form.cleaned_data['email']
phone_number = form.cleaned_data['phone_number']
position = form.cleaned_data['position']

with transaction.atomic():
user = User.objects.create(username=username,email=email)
userinfo = UserInfo.objects.create(user=user,phone=phone_number,position=position)
userinfo.save()
user.save()

return super(TestView, self).form_valid(form)


but I got error like below.

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/manager/test/

Django Version: 1.10.1
Python Version: 3.4.3
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'manager.apps.ManagerConfig',
'mptt']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template C:\Users\Jaemyun\django_real\apa\apa\manager\templates\manager\alltoall.html, error at line 9
'NoneType' object has no attribute 'all' 1 : <select multiple="multiple" data-field-name="groups">
2 : <option value="volvo">Volvo</option>
3 : <option value="hyundai">Hyundai</option>
4 : </select>
5 :
6 : <form action="." method="post">
7 : {% csrf_token %}
8 : <table>
9 : {{ form }}
10 : </table>
11 : <input type="submit" value="Submit" />
12 : </form>

Traceback:

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\core\handlers\exception.py" in inner
39. response = get_response(request)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\core\handlers\base.py" in _get_response
217. response = self.process_exception_by_middleware(e, request)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\core\handlers\base.py" in _get_response
215. response = response.render()

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\response.py" in render
109. self.content = self.rendered_content

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\response.py" in rendered_content
86. content = template.render(context, self._request)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\backends\django.py" in render
66. return self.template.render(context)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\base.py" in render
208. return self._render(context)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\base.py" in _render
199. return self.nodelist.render(context)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\base.py" in render
994. bit = node.render_annotated(context)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\base.py" in render_annotated
961. return self.render(context)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\base.py" in render
1050. return render_value_in_context(output, context)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\template\base.py" in render_value_in_context
1028. value = force_text(value)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\utils\encoding.py" in force_text
76. s = six.text_type(s)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\utils\html.py" in <lambda>
391. klass.__str__ = lambda self: mark_safe(klass_str(self))

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\forms\forms.py" in __str__
123. return self.as_table()

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\forms\forms.py" in as_table
271. errors_on_separate_row=False)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\forms\forms.py" in _html_output
226. 'field': six.text_type(bf),

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\utils\html.py" in <lambda>
391. klass.__str__ = lambda self: mark_safe(klass_str(self))

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\forms\boundfield.py" in __str__
43. return self.as_widget()

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\forms\boundfield.py" in as_widget
101. return force_text(widget.render(name, self.value(), attrs=attrs))

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\forms\widgets.py" in render
610. options = self.render_options(value)

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\forms\widgets.py" in render_options
560. for option_value, option_label in self.choices:

File "C:\Users\Jaemyun\django_real\apa\myenv\lib\site-packages\django\forms\models.py" in __iter__
1114. queryset = self.queryset.all()

Exception Type: AttributeError at /manager/test/
Exception Value: 'NoneType' object has no attribute 'all'

Answer

You can override method get_form_kwargs from FormView class view in order to set inital data for your form.

class YouFormView(FormView):
    teplate_name = 'your template'
    form_class = YourForm


    def get_form_kwargs(self):
        user = self.request.user
        form_kwargs = super(YouFormView, self).get_form_kwargs()
        form_kwargs.update({
            'initial': {
                'uperall': User.objects.filter(username=user.username)
            }
        })
        return form_kwargs

About mixing views: I recommend stick to class based view.