多对多字段的 Django 表单上的逗号分隔文本而不是多项选择

Posted

技术标签:

【中文标题】多对多字段的 Django 表单上的逗号分隔文本而不是多项选择【英文标题】:Comma separated text instead of multiple selection on Django Form for Many to Many Field 【发布时间】:2019-03-27 12:11:57 【问题描述】:

所以,我正在开发一个 web 应用程序来控制我公司在 Django 中的库存(是的,我知道那里有很多开源替代品,我们实际上现在正在使用 fusioninventory,但我不是老板……)。

问题是,一台计算机可以有多个用户,所以我在模型上将它实现为 ManyToMany 字段。这是模型、过滤器和html模板的相关代码。请注意,我使用 django_filters lib 来实现搜索过滤器和 widget_tweaks 来为表单提供一些样式。

models.py

class Computer(models.Model):
    tag = models.CharField(max_length = 20, unique=True)
    users = models.ManyToManyField(User, blank = True, default = 'No_User',)
    TYPE = (
    ('DESK','Desktop'),
    ('LAP','Laptop'),
    )
    computertype = models.CharField(
        max_length = 4,
        choices = TYPE,
    )
    STATUS = (
    ('OK','OK'),
    ('Broken','Broken'),
    ('Unusable','Unusable'),
    )
    computerstatus = models.CharField(
        max_length = 12,
        choices = STATUS,
        default = 'OK',
    )
    model = models.CharField(max_length = 36)
    serial = models.CharField(max_length = 36)
    buy_date = models.DateField()
    modified_date = models.DateTimeField(auto_now=True)
    def __str__(self):
        return self.tag
    def get_absolute_url(self):
        return reverse('computer_detail', args=[str(self.id)])

filters.py

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = User
        fields = 
            'username': ['contains'],
        

class ComputerFilter(django_filters.FilterSet):
    tag = django_filters.CharFilter(lookup_expr="icontains",label = 'Etiqueta',)
    computertype = django_filters.ChoiceFilter(choices = Computer.TYPE, lookup_expr="icontains",label = 'Tipo',)
    computerstatus = django_filters.ChoiceFilter(choices = Computer.STATUS, lookup_expr="icontains",label = 'Estado',)
    **users = UserFilter()**
    from = django_filters.DateFilter(field_name='buy_date', lookup_expr="gt", label='Adquiridos desde',)
    to = django_filters.DateFilter(field_name='buy_date', lookup_expr="lt", label='Hasta',)
    class Meta:
        model = Computer
        fields = ['tag','users','computertype','computerstatus',]

computer_list.html

  <form method="get">
    <div class="well">
      <center><h4><b>Filtro</b></h4></center>
      <center><table>
      <tr>
        <td><div class"form-group">
           filter.form.tag.label_tag
          % render_field filter.form.tag class="form-control" %
        </div></td>
        <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
        <td></td>
      </tr>
      <tr>
        <td><div class"form-group">
           filter.form.computertype.label_tag
          % render_field filter.form.computertype class="form-control" %
        </div></td>
        <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
        <td><div class"form-group">
           filter.form.computerstatus.label_tag
          % render_field filter.form.computerstatus class="form-control" %
        </div></td>
      </tr>
      <tr>
        <td><div class"form-group">
           filter.form.desde.label_tag
          % render_field filter.form.desde class="form-control" type="date" %
        </div></td>
        <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
        <td><div class"form-group">
           filter.form.hasta.label_tag
          % render_field filter.form.hasta class="form-control" type="date" %
        </div></td>
      </tr>
      <tr>
        <td><div class"form-control" input type ="text">
           filter.form.users.label_tag
          % render_field filter.form.users class="form-control" %
        </div></td>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <td></td>
      </tr>
    </table></center>
      <div>
      <p> </p><center><button type="submit" class="btn btn-primary">
        <span class="glyphicon glyphicon-search"></span> Buscar
      </button></center>
      </div>
    </div>
  </form>

可以查看完整代码on github

现在过滤器表单如下所示: See the Image

问题:有没有一种简单的方法可以让表单字段接受如下输入: user1, user2, ... , usern 而不是选择用户?

奖励:有没有办法实现它,使其也具有自动完成功能(例如,我写了 - user1,use - 它显示了所有以“use”开头的用户,所以我可以单击它并将其添加到字段中。

感谢您的宝贵时间。

【问题讨论】:

我相信你正在寻找类似 Select2 的东西~github.com/applegrew/django-select2 【参考方案1】:

你可以使用 ModelMultipleChoiceField

users = ModelMultipleChoiceField()

【讨论】:

以上是关于多对多字段的 Django 表单上的逗号分隔文本而不是多项选择的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多对多字段填充默认表单数据?

django 管理表单上的大型多对多关系

Django 多对多字段过滤器列表

Django admin - 如何在自定义管理表单中为多对多字段添加绿色加号

Django如何过滤多对多字段中的对象,而不是原始查询集

具有多对多关系的Django表单不保存