Python 如何在django通用FormView中使表单字段只读或不可编辑?

Python 如何在django通用FormView中使表单字段只读或不可编辑?,python,django,django-forms,django-views,Python,Django,Django Forms,Django Views,我有一个表单,它用当前登录的用户预先填充页面加载上的用户字段。我想灰显此字段,以便用户不能将其更改为未登录的用户。我希望用户能够更改其余字段。我尝试在模型窗体和视图上使用init函数,但没有成功。任何指点都将不胜感激 forms.py: class PtoRequestForm(forms.ModelForm): class Meta: # Model to be used in the form. model = PtoHistory #

我有一个表单,它用当前登录的用户预先填充页面加载上的用户字段。我想灰显此字段,以便用户不能将其更改为未登录的用户。我希望用户能够更改其余字段。我尝试在模型窗体和视图上使用init函数,但没有成功。任何指点都将不胜感激

forms.py:

class PtoRequestForm(forms.ModelForm):
    class Meta:
        # Model to be used in the form.
        model = PtoHistory
        # Define which model fields to include in the form.
        fields = [
            'user',
            'start',
            'end',
            'leave_type',
        ]
        # Attach input widgets to fields for a friendlier user interface.
        widgets = {
            'start': DateTimeWidget(attrs={'id':'start'}, usel10n = True, bootstrap_version=3),
            'end': DateTimeWidget(attrs={'id':'end'}, usel10n = True, bootstrap_version=3),
    }
class PtoRequestForm(forms.ModelForm):
    class Meta:
        # Model to be used in the form.
        model = PtoHistory
        # Define which model fields to include in the form.
        fields = [
            'start',
            'end',
            'leave_type',
        ]
        # Attach input widgets to fields for a friendlier user interface.
        widgets = {
            'start': DateTimeWidget(attrs={'id':'start'}, usel10n = True, bootstrap_version=3),
            'end': DateTimeWidget(attrs={'id':'end'}, usel10n = True, bootstrap_version=3),
        }
views.py:

class IndexView(FormView):
    template_name = 'accounts/index.html'
    form_class = PtoRequestForm
    success_url = '/accounts'
    # Pre-populates the form with the specified values on page load.
    def get_initial(self):
        return {'user': self.request.user}

    # Function runs when form is submitted. Do whatever needed to the form before it's saved to the db.
    def form_valid(self, form):
        form.save()
        return super(IndexView, self).form_valid(form)

    # Function runs on page load. Gather any information needed for the template.
    def get_context_data(self, **kwargs):
        # Initialize context
        context = super(IndexView, self).get_context_data(**kwargs)

        # Grab all ptoHistory records from the database, selecting only the values desired.
        pto_history = PtoHistory.objects.values('start', 'end', 'pk', 'user_id')
        # Convert the django queryset to json so that fullcalendar can work with it on the frontend.
        json_pto_history = json.dumps(list(pto_history), cls=DjangoJSONEncoder)
        # Save the converted json to the context to be returned to the front end.
        context['ptoHistory'] = json_pto_history
        return context
def form_valid(self, form):
        new_form = form.save(commit=False)
        new_form.user = self.request.user
        new_form.save()
        return super(IndexView, self).form_valid(form)
这是我表格的截图。用户不能更改用户字段,但其他字段可以更改


您可以按如下方式添加它:

class PtoRequestForm(forms.ModelForm):
    class Meta:
        # Model to be used in the form.
        model = PtoHistory
        # Define which model fields to include in the form.
        fields = [
            'user',
            'start',
            'end',
            'leave_type',
        ]
        # Attach input widgets to fields for a friendlier user interface.
        widgets = {
            'start': DateTimeWidget(attrs={'id':'start'}, usel10n = True, bootstrap_version=3),
            'end': DateTimeWidget(attrs={'id':'end'}, usel10n = True, bootstrap_version=3),}

    def __init__(self, *args, **kwargs):
         super(PtoRequestForm, self).__init__(*args, **kwargs)
         self.fields['user'].widget.attrs['readonly'] = True

在我的模型表单中,我没有像这样包含“用户”字段:

forms.py:

class PtoRequestForm(forms.ModelForm):
    class Meta:
        # Model to be used in the form.
        model = PtoHistory
        # Define which model fields to include in the form.
        fields = [
            'user',
            'start',
            'end',
            'leave_type',
        ]
        # Attach input widgets to fields for a friendlier user interface.
        widgets = {
            'start': DateTimeWidget(attrs={'id':'start'}, usel10n = True, bootstrap_version=3),
            'end': DateTimeWidget(attrs={'id':'end'}, usel10n = True, bootstrap_version=3),
    }
class PtoRequestForm(forms.ModelForm):
    class Meta:
        # Model to be used in the form.
        model = PtoHistory
        # Define which model fields to include in the form.
        fields = [
            'start',
            'end',
            'leave_type',
        ]
        # Attach input widgets to fields for a friendlier user interface.
        widgets = {
            'start': DateTimeWidget(attrs={'id':'start'}, usel10n = True, bootstrap_version=3),
            'end': DateTimeWidget(attrs={'id':'end'}, usel10n = True, bootstrap_version=3),
        }
然后在我的form_valid函数中,我将当前登录的用户附加到数据库中,如下所示:

views.py:

class IndexView(FormView):
    template_name = 'accounts/index.html'
    form_class = PtoRequestForm
    success_url = '/accounts'
    # Pre-populates the form with the specified values on page load.
    def get_initial(self):
        return {'user': self.request.user}

    # Function runs when form is submitted. Do whatever needed to the form before it's saved to the db.
    def form_valid(self, form):
        form.save()
        return super(IndexView, self).form_valid(form)

    # Function runs on page load. Gather any information needed for the template.
    def get_context_data(self, **kwargs):
        # Initialize context
        context = super(IndexView, self).get_context_data(**kwargs)

        # Grab all ptoHistory records from the database, selecting only the values desired.
        pto_history = PtoHistory.objects.values('start', 'end', 'pk', 'user_id')
        # Convert the django queryset to json so that fullcalendar can work with it on the frontend.
        json_pto_history = json.dumps(list(pto_history), cls=DjangoJSONEncoder)
        # Save the converted json to the context to be returned to the front end.
        context['ptoHistory'] = json_pto_history
        return context
def form_valid(self, form):
        new_form = form.save(commit=False)
        new_form.user = self.request.user
        new_form.save()
        return super(IndexView, self).form_valid(form)

您可以覆盖uuu init\uuuu\PtoRequestForm,并在其中添加self.fields['user'].widget.attrs['readonly']=true在代码中的具体位置?我试过几种类似的方法,它们要么不改变任何东西,要么抛出错误。太棒了,我们正在取得进展。执行此操作后,字段变灰,但我仍然可以选择下拉菜单并更改用户。这可能与“只读”有关吗?是否还有另一个属性可以工作,用户甚至无法选择下拉菜单?如果必须使其选择元素。您可以添加disabled attribute=True。问题是,如果您这样做了,它将不会在提交后发回。您还可以将小部件更改为textfield,如下所示。self.fields['user'].widget=TextInput()是的,这就是我刚才读到的。我是否可以禁用它,并在提交后在后端启动用户?如果您将小部件更改为TextInput,则不必禁用它,readonly属性将执行此操作,并将其发送到后端。如果您决定通过Selectbox,则有两个选项。如果该用户已附加到请求,则可以通过request.user访问该用户。如果没有,则必须添加一个带有用户名的隐藏字段。