当前位置: 首页 > 知识库问答 >
问题:

仅具有view权限的Django模型表单将所有字段置于exclude

魏明亮
2023-03-14

在默认(django admin)更改视图中使用自定义ModelForm,如果为仅具有视图权限的用户呈现表单(在django 2.1中新增),则会给我一个空变量self.fields

这是我的代码:

# models.py

class Door(ValidateOnSaveMixin, models.Model):
    ...

    motor_type = models.ForeignKey(
        MotorType,
        on_delete=models.SET_NULL,
        default=None,
        blank=True,
        null=True)
    ...
    door_type = models.CharField(
        max_length=3,
        choices=DOOR_TYPES,
        null=True,
        default=None)
    ...
    vehicle_variant = models.ForeignKey(
        VehicleVariant,
        on_delete=models.CASCADE)

    class Meta:
        unique_together = ("vehicle_variant", "location", "motor_type")

    ...



# admin.py

@admin.register(Door)
class DoorAdmin(ImportExportModelAdmin):
    form = DoorAdminForm

    list_display = ('descriptor', 'get_customer_link', 'get_variant', 'location', 'get_motor_type_link',
                    'window_type', 'door_type', 'drum_diameter', 'dist_per_motor_rotation')
    fields = ('vehicle_variant', 'description', 'location', 'motor_type',
              'drum_diameter', 'window_type', 'door_type')

    ...

# forms.py

class DoorAdminForm(ModelForm):

    class Meta:
        model = Door
        fields = '__all__'
        widgets = {
            'motor_type': DoorMotorTypeWidget,
        }

    def __init__(self, *args, **kwargs):
        super(DoorAdminForm, self).__init__(*args, **kwargs)
        # this line is crashing on access with a user who has only the view permission, as self.fields is empty
        self.fields['vehicle_variant'].queryset = VehicleVariant.objects.all().prefetch_related('customer').order_by('customer__name', 'name')

根本原因与DoorAdminForm中元类的exclude属性有关。无论我对fields/exclude属性写了什么,模型的所有字段总是自动放入exclude列表,并防止self.fields被填充。这让我的代码崩溃了。

当然,我可以在self.fields中检查'verhicle_variant',但我不明白这种行为的原因。我在django源代码中也找不到用所有模型字段填充exclude属性的部分。

有人知道这是不是故意的吗?这种行为(忽略元类的字段和exclude属性)的根本原因是什么?


共有1个答案

东方吕恭
2023-03-14

将所有字段放入exclude的位置如下:https://github.com/django/django/blob/cf79f92abee2ff5fd4fdcc1a124129a9773805b8/django/contrib/admin/options.py#l674

我从来没有使用过django admin的“查看”权限。我也没有找到很多关于它应该是什么样子的信息:django-admin附带了添加和更改视图,但没有viewonly-view?看起来它并不知道如何处理没有“更改”权限的用户。它将它们引导到change_view,然后注意到它们不允许更改任何内容,所以它显示一个空表单?
我想您可以将viewonly-view的所有字段声明为readonly?

更新:
字段vehicle_variant不会在form.fields中,因为它仍然会由于没有更改权限而被排除,但至少您不会在表单的init上崩溃。我仍然不知道没有更改权限的change_view应该是什么样子,除了所有内容都是只读的。

class DoorAdminForm(ModelForm):
    qs = VehicleVariant.objects.prefetch_related('customer').order_by('customer__name', 'name')
    model_field = Door._meta.get_field('vehicle_variant')

    vehicle_variant = model_field.formfield(queryset=qs)

    class Meta:
        model = Door
        fields = '__all__'
        widgets = {
            'motor_type': DoorMotorTypeWidget,
        }
 类似资料:
  • 我有两种型号: 模式: GraphQL的目标之一是性能。为此,GraphQL必须通过GraphQL请求(例如:GraphiQL)仅向数据库请求所请求的字段 如果我请求以下查询: 石墨烯-django库生成以下SQL: 它得到了模型的所有字段!与API Rest问题相同,不符合GraphQL指南。 如果我从模型中请求字段,我希望查询是: 外键如何解决这个问题?

  • 问题内容: 我正在从事类似在线商店的工作。我正在制作一个表格,客户在其中购买商品,她可以选择要购买的商品数量。但是,在她购买的每件商品上,她都需要选择其颜色。因此,字段的数量是不固定的:如果客户购买3件商品,她应该得到3个用于选择颜色的盒子,如果她购买7件商品,则应该得到7个这样的盒子。 我将使用JavaScript使HTML表单字段显示和消失。但是我该如何在Django表单类上处理呢?我看到表单

  • 问题内容: 如何将Django模型对象及其所有字段转换为字典?理想情况下,所有内容都包含带有的外键和字段。 让我详细说明。假设我有一个类似以下的Django模型: 在终端中,我已执行以下操作: 我想将其转换为以下字典: 问题答案: 有多种方法可以将实例转换为字典,并具有不同程度的转角案例处理和接近所需结果的程度。 1。 instance.dict 哪个返回 到目前为止,这是最简单的方法,但是缺少,

  • 问题内容: 假设我们在Django中有一个定义如下的模型: 名称字段不是唯一的,因此可以具有重复的值。我需要完成以下任务:从模型中选择具有至少一个name字段重复值的所有行。 我知道如何使用普通的SQL来做到这一点(可能不是最好的解决方案): 因此,可以使用django ORM选择它吗?还是更好的SQL解决方案? 问题答案: 尝试: 这与使用Django所获得的效果非常接近。问题在于这将返回一个w

  • 我们需要为我们的客户填写一个表格,并获得一个PDF,他们可以打印,签名 但我很难确定页码。由于表单由多个模板组合而成,我必须用PDFBox修复页码。到目前为止,我们在每页上都使用了一个样式化的输入字段。但由于它们都有相同的名字,我不能单独填写。 我可以以某种方式拆分或克隆字段并为它们提供单独的名称,以便我可以单独填充它们吗?当然,样式应该保持不变。

  • 问题内容: 在我的模型中,我想要一个包含三联列表的字段。例如。是否存在可以将这些数据存储在数据库中的字段? 问题答案: 你可以使用JSON将其转换为字符串并将其存储为字符串。 例如, 你可以在类中添加方法以自动为你转换。