【问题标题】:Django admin change form widget from integer dropdown to checkboxDjango 管理员将表单小部件从整数下拉列表更改为复选框
【发布时间】:2020-09-22 23:55:34
【问题描述】:

我有以下模型,其中包含不同状态的正小整数字段:

class Shops(models.Model):

   STATUS_CHOICES = [
          (0, 'Inactive'),
          (1, 'Active'),
          (2, 'Closed'),
          (3, 'Transferred'),
      ]
  status = models.PositiveSmallIntegerField("Status", choices=STATUS_CHOICES, null=True, blank=True)

管理站点上的状态小部件将生成为选择框

但我希望它是一个复选框,复选框值为 0 和 1 跟随 STATUS_CHOICE,并且我已经处理列表页面以仅按状态 = 0 或 1 进行过滤

在管理页面上的状态是这样的:

我试图像这样覆盖管理员更改表单:

#Form 

class ShopsForm(forms.ModelForm):

    status = forms.CheckboxInput()

    def __init__(self, *args, **kwargs):
        super(ShopsForm, self).__init__(*args, **kwargs)
        self.initial['status'] = False
        if self.instance:
            if self.instance.status is not None:
                try:
                    self.initial['status'] = False
                    if self.instance.status == 1:
                        self.initial['status'] = True
                except:
                    pass

        self.fields['status'].label = "Active"

    def clean_status(self):
        if self.cleaned_data['status'] is not None:
            data = self.cleaned_data['status']
        else:
            data = None

        return data

    class Meta:
        model = Shops
        exclude = ['status']

#ModelAdmin

class ShopsAdmin(admin.ModelAdmin):
    list_per_page = 50

    form = ShopsForm

    list_display = (
        ...
        'status'
    )

    list_display_links = (
        ...
        'status'
    )

    fields = (
        ...
        'status',
    )

    readonly_fields = (
        'id',
    )


    def save_model(self, request, obj, form, change):
        obj.status = 0
        if form.cleaned_data['status'] == True:
            obj.status = 1
        obj.save()
        return super(ShopsAdmin, self).save_model(request, obj, form, change)

    pass

admin.site.register(Shops, ShopsAdmin)

但是当我转到更改表单时出现以下错误:

File "/app/backend/admin.py", line 2388, in __init__
web_1         |     self.fields['status'].label = "Active"
web_1         | KeyError: 'status'

我已经在表单中设置了一个自定义状态字段,我很困惑,希望有人可以帮助我

编辑:

我将status = forms.CheckboxInput() 更改为status = forms.IntegerField(required=False, widget=forms.CheckboxInput),现在根据字段显示复选框

但是当我尝试取消勾选并保存它时返回验证错误并且不会让我更改

输入一个整数。

【问题讨论】:

  • 不需要 exclude = ['status']
  • 表单有一个带有 label = active 的状态字段,但它是一个下拉菜单,而不是 @Blackdoor 复选框

标签: python django django-forms django-admin


【解决方案1】:

我发现了问题,我应该使用 forms.BooleanField() 而不是 forms.CheckboxInput()

我将表单更改为以下内容:

class ShopsForm(forms.ModelForm):

    active = forms.BooleanField(required=False)
    def __init__(self, *args, **kwargs):
        super(StakingForm, self).__init__(*args, **kwargs)
        self.initial['active'] = False
        if self.instance:
            if self.instance.status is not None:
                try:
                    self.initial['active'] = False
                    if self.instance.status == 1:
                        self.initial['active'] = True
                except:
                    pass

        self.fields['active'].label = "Active"

    def clean_active(self):
        if self.cleaned_data['active'] is not None:
            data = self.cleaned_data['active']
        else:
            data = None

        return data

    class Meta:
        model = Shops
        exclude = []

在管理员中,我从字段元组中删除 status

fields = (
        ....
        'active',
        #remove 'status'
    )

#and add override save so checkbox value save into status integer column

ef save_model(self, request, obj, form, change):
   obj.status = 0
   if form.cleaned_data['active'] == True:
      obj.status = 1
   obj.save()
   return super(ShopsAdmin, self).save_model(request, obj, form, change)

现在我有一个使用 IntegerField() 选择值 1 和 2 的复选框:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-29
    • 2019-04-25
    • 2018-03-09
    • 2013-07-12
    • 1970-01-01
    • 2016-04-27
    • 2011-09-29
    • 2011-05-19
    相关资源
    最近更新 更多