Django:具有未保存的动态表单字段的 CreateView 对象
Django: CreateView object with dynamic form fields not saved
我设置了一个有效的 CreateView。但是,当我将我的模型字段之一 ('erlaubte_pruefer') 动态化时,该对象不再保存。
我已经尝试过其他帖子中建议的许多解决方案,例如
- get user variable 在 get_form_kwargs() 中,
- get_form() 中的 limit the field choices 而不是 forms.py
- 不要使用 CreateView
但我就是做不到。我没有收到错误或异常,表单只是再次呈现。
非常感谢您的意见。谢谢!
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')
编辑:
谢谢@Daniel Rosemann 的回复。我将您的代码包含在我的代码中,但出现此错误:
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().
再次感谢!
您已经更改了表单的签名,现在第一个位置参数是 user
,而不是 data
。但是您已将 get_form
定义为仅通过 user
,并且永远不会通过 data
;所以表单永远不会获取任何数据,因此永远不会有效。
让用户成为 kwarg:
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)
并在视图中删除您对 get_form
的定义,而是定义 get_form_kwargs
以传递给用户:
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
另请注意,您在 form_valid
中做的工作太多了;调用 form.save
已经设置了表单中的字段,例如 "erlaubte_pruefer" 和 "okay",因此您无需手动设置它们。
(最后,盲目地捕获所有错误完全没有用,只是 return 一个模糊的 "an error has occurred" 消息。它隐藏了会告诉你发生了什么的日志记录,并且没有' 给用户任何有用的信息。只捕获你知道你会处理的错误;删除它 try/except 并让 Django 显示默认错误页面。)
我设置了一个有效的 CreateView。但是,当我将我的模型字段之一 ('erlaubte_pruefer') 动态化时,该对象不再保存。
我已经尝试过其他帖子中建议的许多解决方案,例如 - get user variable 在 get_form_kwargs() 中, - get_form() 中的 limit the field choices 而不是 forms.py - 不要使用 CreateView
但我就是做不到。我没有收到错误或异常,表单只是再次呈现。
非常感谢您的意见。谢谢!
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')
编辑:
谢谢@Daniel Rosemann 的回复。我将您的代码包含在我的代码中,但出现此错误:
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().
再次感谢!
您已经更改了表单的签名,现在第一个位置参数是 user
,而不是 data
。但是您已将 get_form
定义为仅通过 user
,并且永远不会通过 data
;所以表单永远不会获取任何数据,因此永远不会有效。
让用户成为 kwarg:
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)
并在视图中删除您对 get_form
的定义,而是定义 get_form_kwargs
以传递给用户:
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
另请注意,您在 form_valid
中做的工作太多了;调用 form.save
已经设置了表单中的字段,例如 "erlaubte_pruefer" 和 "okay",因此您无需手动设置它们。
(最后,盲目地捕获所有错误完全没有用,只是 return 一个模糊的 "an error has occurred" 消息。它隐藏了会告诉你发生了什么的日志记录,并且没有' 给用户任何有用的信息。只捕获你知道你会处理的错误;删除它 try/except 并让 Django 显示默认错误页面。)