在 django View 类中访问表单“字段”
Posted
技术标签:
【中文标题】在 django View 类中访问表单“字段”【英文标题】:Access form 'fields' in django View class 【发布时间】:2021-09-05 05:15:19 【问题描述】:我正在尝试访问基于类的视图中的“字段”属性
这是我的 forms.py 的示例:
from django import forms
from .models import ErrorEvent
class ErrorEventForm(forms.ModelForm):
class Meta:
model = HumanErrorEvent
# fields =
exclude = ['event_id', 'user_modified', 'date_modified']
widgets =
'owner': forms.TextInput(),
那么这是我的看法:
class ErrorCreateView(CreateView):
template_name = "forms/form.html"
form_class = ErrorEventForm
model = ErrorEvent
def get_context_data(self, **kwargs):
if not self.request.user.groups.filter(name='leaders').exists():
self.form_class.fields['owner'].widget = forms.HiddenInput()
context = super(ErrorCreateView, self).get_context_data(**kwargs)
return context
我得到的错误是:
AttributeError: type object 'ErrorEventForm' has no attribute 'fields'
由于这一行:
self.form_class.fields['owner'].widget = forms.HiddenInput()
是否无法访问视图中的“字段”属性?如果没有,有没有办法根据用户所在的组隐藏“所有者”表单字段?
提前感谢您的所有帮助!
【问题讨论】:
为什么在提交表单时隐藏用户,而不是简单地使用request.user
?
这是通常的做法,但我希望能够让某些人有权更改所有者或以其他人的名义创建所有者。
然后您可以在表单中添加ModelChoiceField
。
这如何解决我的问题?
@mike_gundy123 表单的fields
属性仅在实例化时添加到表单中。表单类本身没有它。 get_context_data
也不是最好的覆盖方法。
【参考方案1】:
表单的fields
属性只有在表单被实例化时才添加,表单类本身没有。此外,get_context_data
不是覆盖做此类事情的最佳方法,更好的方法可能是 get_form
,因此您可以编写如下内容:
def get_form(self, form_class=None):
form = super().get_form(form_class=form_class)
form.fields['owner'].widget = forms.HiddenInput()
return form
但我们仍然可以做得比这更好!这样的逻辑不应该属于表单类本身吗?因此,最好将用户简单地传递给表单类。您可以通过覆盖 get_form_kwargs
和表单 __init__
方法来做到这一点:
# Form
class ErrorEventForm(forms.ModelForm):
class Meta:
model = HumanErrorEvent
# fields =
exclude = ['event_id', 'user_modified', 'date_modified']
widgets =
'owner': forms.TextInput(),
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user and not user.groups.filter(name='leaders').exists():
del self.fields['owner'] # Remove the field itself from the form
self.instance.owner = user # Set the user as the owner
# View
class ErrorCreateView(CreateView):
template_name = "forms/form.html"
form_class = ErrorEventForm
model = ErrorEvent
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
【讨论】:
感谢您的帮助!这些线有什么意义? super().__init__(*args, **kwargs) kwargs = super().get_form_kwargs() 另外我将如何在 html 端处理这个问题? form.owner|as_crispy_field 但是当我删除它时我得到一个错误,因为它不存在 @mike_gundy123super().<method_call>
只是调用了 super 方法,我相信您已经在使用类似super(ErrorCreateView, self).get_context_data(**kwargs)
的方法(您可以跳过 python3 中的两个参数)?至于那个错误,我原以为您是直接渲染表单,要解决它,您可以将其括在 if 中:% if form.owner %<div class="col-md-3"> form.owner|as_crispy_field </div>% endif %
我正在对现有系统进行更改,所以我不写那部分哈哈。感谢你的帮助!它有效!以上是关于在 django View 类中访问表单“字段”的主要内容,如果未能解决你的问题,请参考以下文章