【问题标题】:Making Django forms return forms.instance in templates使 Django 表单在模板中返回 forms.instance
【发布时间】:2017-01-12 09:48:10
【问题描述】:

我的用户拥有复杂的用户定义权限。但为了更简单,让我们假设每个用户只有 read-onlywrite 权限。

我正在使用 Django 表单来编辑和保存模型对象。 我的目标是在 Django HTML 模板中为那些有权编辑给定模型实例的用户呈现<input>,如果用户只有只读权限。

目前,我的 Django 模板中有以下代码来实现这一点:

{%if user.has_permission_to_edit %}
    {{my_form.my_field}}
{% else %}
    {{my_form.instance.my_field}}
{% endif %}

这里是my_form

class MyForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)   
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control input-sm'
            if field.required == True: 
                field.widget.attrs['required'] = ''
    class Meta:
        model = MyModel
        fields = ('my_field',)

模板中代码的问题是我必须使用多个 {% if %}{% else %} 块。我对 Django 比较陌生,而且我知道有很多高级工具使 Django 代码可能超级 DRY,所以我想问你们,组织我在模板中描述的内容的最 DRY 方法是什么。具体来说,有没有办法让 Django 表单根据表单定义中指定的某些条件返回实例值?还是我必须使用一些使用定义的标签?或者也许使用了一些完全不同的架构来实现这些目标?

【问题讨论】:

  • 我不确定我是否理解您想要实现的目标?您正在编辑模型对象吗?如果用户有编辑权限,行为会如何变化?
  • 您要在哪种类型的字段中显示硬编码值?是文本字段吗?
  • 嗯,它可以是文本字段、数值、复选框...任何东西。基于各自模型字段类型的类型

标签: django django-forms


【解决方案1】:

根据我对您问题的理解,您希望传递从您的数据源获取的数据实例。

from .forms import MyForm
from django.shortcuts import render

假设您在 views.py 级别创建了一个 forms.py 文件。

从数据源获取数据(详情为下例中的模型)

detail_instance = Detail.objects.get(user=request.user.id)
reg_form = MyForm(instance=detail_instance or None)
# In case of edit scenario you can pass in the post params to the form as well
reg_form = MyForm(request.POST, instance=detail_instance)
# Or form with uploads
reg_form = MyForm(request.POST, request.FILES, instance=detail_instance)

现在,一旦我们的 reg_form 参数中有数据,我们就可以在模板中传递它

return render(request, 'applicant/register.html', { 'my_form' : reg_form})

随心所欲,在模板中使用 my_form 变量。

基于更新后的问题

您可以将参数传递给表单的init函数

reg_form = MyForm(exist = exist, some_param = param_value, instance=detail_instance or None)

传递param后,就可以在form的init函数中获取param并处理

class MyForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        exist = kwargs.pop('exist', None)
        pk_reg = kwargs.pop('param', None)
        super(MyForm, self).__init__(*args, **kwargs)
        #do some stuff with you custom params here
        if exist == True or pk_reg:
            self.fields['username'].widget.attrs['readonly'] = True

上述方法还有另一种选择,即为单独的权限设置单独的表单并根据用户权限调用适当的表单。

【讨论】:

    猜你喜欢
    • 2012-06-21
    • 2018-12-28
    • 1970-01-01
    • 2015-10-14
    • 2016-04-19
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 2019-06-02
    相关资源
    最近更新 更多