【问题标题】:Django formsDjango 表单
【发布时间】:2009-03-09 19:58:35
【问题描述】:

我曾问过一个与此有关的问题。但我认为直接问我的问题会更好。 我有一个与其他两个表“域”和“组”有多对多关系的“用户”表。 因此,在管理界面中,我将 Groups 和 Domains 视为 2 ModelMultipleChoiceFields。 但我想以更加用户友好的方式在 UI 上呈现它们。 我想在域和组中显示每个可用的选项,并根据用户属性选择/取消选择复选框。 想知道我是否可以在管理员中执行此操作,或者我需要独立于管理员编写自己的视图。

【问题讨论】:

    标签: python django django-admin


    【解决方案1】:

    我认为内置小部件 CheckboxSelectMultiple 可以满足您的需求。如果没有,您将不得不创建自己的小部件。 documentation for widgets 是一个很好的起点。最简单的开始方法是从 Django 源中复制现有的小部件并对其进行修改。

    【讨论】:

      【解决方案2】:

      准确地说,它是 Django 管理员在 ManyToManyField 的情况下选择显示的小部件。 在这种情况下,您觉得它的 SelectMultiple 小部件对用户不太友好。

      很简单的部分是,您始终可以在使用自己的 ModelForm 时选择小部件。 但是如果你想在 Django Admin 中这样做,你需要一个往返。看看这个。

      from django.forms import widgets
      from django.contrib import admin
      
      class MyModelAdmin(admin.ModelAdmin):
          def formfield_for_manytomany(self, db_field, request=None, **kwargs):
          """
          Get a form Field for a ManyToManyField.
          """
          # If it uses an intermediary model, don't show field in admin.
          if db_field.rel.through is not None:
              return None
      
          if db_field.name in self.raw_id_fields:
              kwargs['widget'] = admin.widgets.ManyToManyRawIdWidget(db_field.rel)
              kwargs['help_text'] = ''
          elif db_field.name in (list(self.filter_vertical) + list(self.filter_horizontal)):
              kwargs['widget'] = admin.widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
          else:
              kwargs['widget'] = widgets.CheckboxSelectMultiple()
              kwargs['help_text'] = ''
      
          return db_field.formfield(**kwargs)
      

      现在,在 admin.py 中定义你的日常管理员为

      class SomeModelAdmin(MyModelAdmin):
          search_fields = ['foo', 'bar']
          list_display   = ('foo',)
          ordering       = ('-bar',)
      
      admin.site.register(SomeModel, SomeModelAdmin)
      

      您现在将在 DJango Admin 中获得复选框。当然,您需要对 CSS 进行一些更改。

      【讨论】:

        【解决方案3】:

        它实际上在管理中默认使用模型表单。所以,你需要覆盖它。

        from django import forms
        from django.forms import widgets
        
        class DomainForm(forms.ModelForm):
        
            field2 = YourField(widget=widgets.CheckboxSelectMultiple)
        
            class Meta:
                model = Domain()
                fields = ('field1', 'field2')
        

        所以,在这种情况下,我已经覆盖了默认的 FIELD2 字段类型。

        【讨论】:

        • -1 我认为单个 CheckboxInput 不能用于 ManyToMany 字段。
        【解决方案4】:

        我不完全确定我理解你想要做什么,但也许像 filter_horizontal 这样的东西会做你想做的事。

        【讨论】:

          【解决方案5】:

          您可以更改 django 管理界面字段小部件

          from django.forms import widgets
          
          class UserAdmin(admin.ModelAdmin):
              model = User
          
              def formfield_for_manytomany(self, db_field, request=None, **kwargs):
                  if db_field.name == 'domain' or db_field.name == 'groups':
                  kwargs['widget'] = widgets.CheckboxSelectMultiple()
          
                  # or just make all the manytomany fields as checkbox
          
                  kwargs['widget'] = widgets.CheckboxSelectMultiple()
          
                  return db_field.formfield(**kwargs)
          
              # for other field
              def formfield_for_dbfield(self, db_field, **kwargs):
                  .....
                  return super(UserAdmin, self).formfield_for_dbfield(db_field, **kwargs)
          
          admin.site.register(User, UserAdmin)
          

          【讨论】:

            猜你喜欢
            • 2011-07-18
            • 2020-11-17
            • 1970-01-01
            • 2015-02-24
            • 2011-01-08
            • 2017-01-02
            • 2011-04-01
            • 2021-05-16
            • 2010-12-29
            相关资源
            最近更新 更多