Python 仅具有查看权限的Django模型表单将所有字段置于排除状态

Python 仅具有查看权限的Django模型表单将所有字段置于排除状态,python,django,django-forms,Python,Django,Django Forms,如果在我的默认(django admin)更改视图中使用自定义模型表单,则会给我一个空变量self.fields(django 2.1中新增的)如果该表单仅为具有查看权限的用户呈现 这是我的代码: # models.py class Door(ValidateOnSaveMixin, models.Model): ... motor_type = models.ForeignKey( MotorType, on_delete=models.SE

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

这是我的代码:

# 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
中的Meta类的exclude属性有关。 无论我如何写入字段/排除属性,模型的所有字段都会自动放入排除列表,并防止填充
self.fields
。这使得我的代码崩溃

当然,我可以在self.fields中检查“verhicle\u variant”,但我不理解这种行为的原因。我在django源代码中也找不到用所有模型字段填充exclude属性的部分


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

将所有字段放入
exclude
的点如下:

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


更新:
字段
vehicle\u variant
将不在
表单中。字段
,因为由于没有更改权限,它仍将被排除在外,但至少您不会在表单的init中崩溃。除了所有内容都是只读的之外,我仍然不知道没有更改权限的更改视图应该是什么样子

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,
        }

谢谢你的链接!我没发现。我认为他们在CRUD中实现R时做得很好:)因此viewonly视图实际上是change视图,但不允许更改,这对我来说很有意义。如果我在admin类中使用get_form方法,我可以省略change参数并阻止excludes。但我目前不确定它会有什么副作用。我会调查的。用其他方法设置
vehicle\u variant
的查询集可能更容易。在
DoorAdminForm
上显式声明字段?如何执行此操作?我决定不使用get_form方法,而是在self中检查键。字段作为仅视图视图中的字段,我实际上不需要查询优化。但是从if语句来看,仍然不清楚为什么我需要检查密钥。所以我想有一些自我记录的实现方式。但现在我很高兴在这些行上发表一些评论。更新了我的帖子,我希望我没有遗漏一些明显的东西。我也使用了你的更新建议,它适用于外国关键关系,但不适用于许多人。