Reputation: 59
I set up a working CreateView. However, when I made one of my modelform fields ('erlaubte_pruefer') dynamic, the object is not saved anymore.
I've tried many solutions suggested in other posts, e.g. - get user variable in get_form_kwargs(), - limit the field choices in get_form() instead of forms.py - don't use CreateView
but I just can't make it work. I don't get an error or exception, the form is only rendered again.
I would highly appreciate your input. Thank you!
forms.py
class Checklisten_Reinigung_Form(forms.ModelForm):
class Meta:
model = Checklisten_Reinigung
fields = ['okay',
'raum_verbindung',
'ausfuehrer',
'erlaubte_pruefer'
]
# user should only choose from those objects that were created by himself
def __init__(self, user, *args, **kwargs):
super(Checklisten_Reinigung_Form, self).__init__(*args, **kwargs)
self.fields['erlaubte_pruefer'].queryset =
Pruefer.objects.filter(firmenzugehoerigkeit=user)
views.py
class Checklisten_Reinigung_Create_View(LoginRequiredMixin, CreateView):
template_name = 'checklisten/checklisten_form.html'
def get_context_data(self, **kwargs):
context = super(Checklisten_Reinigung_Create_View,
self).get_context_data(**kwargs)
context['mymodel'] = Checklisten_Reinigung()
return context
# if I leave out get_form() the object is successfully saved
# but the user's choice is not limited
def get_form(self, form_class=None):
form = Checklisten_Reinigung_Form(user=self.request.user)
return form
def form_valid(self, form):
self.object = form.save(commit=False)
try:
self.object.pruefende_firma = self.request.user
self.object.bezeichnung = self.object.bezeichnung
self.object.ausfuehrer = form.cleaned_data['ausfuehrer']
self.object.erlaubte_pruefer =
form.cleaned_data['erlaubte_pruefer']
self.object.okay = form.cleaned_data['okay']
self.object.raum_verbindung= form.cleaned_data['raum_verbindung']
self.object.save()
return HttpResponseRedirect(self.get_success_url())
except:
messages.error(self.request, 'Es ist ein Fehler aufgetreten.')
return self.render_to_response(self.get_context_data(form=form(user=self.request.user)))
def get_success_url(self):
messages.success(self.request, 'Checkliste erfolgreich gespeichert.')
return reverse('checkliste-startseite')
EDIT:
Thank you, @Daniel Rosemann for your reply. I included your code into mine but get this error:
Traceback:
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\core\handlers\base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\views\generic\base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\contrib\auth\mixins.py" in dispatch
52. return super().dispatch(request, *args, **kwargs)
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\views\generic\base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\views\generic\edit.py" in get
168. return super().get(request, *args, **kwargs)
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\views\generic\edit.py" in get
133. return self.render_to_response(self.get_context_data())
File "C:\Users\Mars\Desktop\morecooking_now\morecooking_now\checklisten\views.py" in get_context_data
372. context = super(Checklisten_Reinigung_Create_View, self).get_context_data(**kwargs)
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\views\generic\edit.py" in get_context_data
66. kwargs['form'] = self.get_form()
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\views\generic\edit.py" in get_form
32. form_class = self.get_form_class()
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\views\generic\edit.py" in get_form_class
93. model = self.get_queryset().model
File "C:\Users\Mars\Anaconda3\lib\site-packages\django\views\generic\detail.py" in get_queryset
73. 'cls': self.__class__.__name__
Exception Type: ImproperlyConfigured at /checklisten/reinigung/neu/
Exception Value: Checklisten_Reinigung_Create_View is missing a QuerySet. Define Checklisten_Reinigung_Create_View.model, Checklisten_Reinigung_Create_View.queryset, or override Checklisten_Reinigung_Create_View.get_queryset().
Thank you again!
Upvotes: 0
Views: 2020
Reputation: 599866
You have changed the signature of the form so that the first positional argument is now user
, not data
. But you've defined get_form
to only ever pass user
, and never data
; so the form never gets any data and therefore can never be valid.
Make user a kwarg instead:
def __init__(self, *args, **kwargs): # no user here
user = kwargs.pop('user', None)
super(Checklisten_Reinigung_Form, self).__init__(*args, **kwargs)
self.fields['erlaubte_pruefer'].queryset =
Pruefer.objects.filter(firmenzugehoerigkeit=user)
and in the view, remove your definition of get_form
and instead define get_form_kwargs
to pass the user:
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
Note also, you're doing too much work in form_valid
; the call to form.save
will already have set the fields in the form, such as "erlaubte_pruefer" and "okay", so you don't need to set them manually.
(And finally, it is absolutely no use at all to blindly catch all errors and just return a vague "an error has occurred" message. That hides the logging that will tell you what happened, and doesn't give the user any useful information. Only catch the errors you know you will deal with; remove that try/except and let Django show the default error page.)
Upvotes: 1