代码之家  ›  专栏  ›  技术社区  ›  Jon Mooring

扩展表单。选择多个而不丢失值

  •  0
  • Jon Mooring  · 技术社区  · 16 年前

    我有一个模型表单,我正在为它编写一个自定义小部件,以替换多对多表单。使用jQuery FCBKcomplete小部件选择多个字段。虽然替换“multiselect”元素可以正常工作,但它不再为“multiselect”提取选项。

    这是我的小部件:

    class FCBKcompleteWidget(forms.SelectMultiple):
        def _media(self):
            return forms.Media(js=(reverse('appstatic',
                                           args=['js/jquery.fcbkcomplete.min.js']),
                                   reverse('appstatic',
                                           args=['js/init-fcbkcomplete.js'])),
                               css={'all': (reverse('appstatic',
                                                    args=['css/jquery.fcbkcomplete'
                                                          '.css']),)})
    
        media = property(_media)
    

    这是我的表格:

    class BlogForm(forms.ModelForm):
        class Meta(object):
            model = models.Blog
            exclude = ('slug',)
    
        def __init__(self, *args, **kwargs):
            super(BlogForm, self).__init__(*args, **kwargs)
            self.fields['description'].widget = TinyMCEWidget()
    
            fcbkcomplete_fields = ['categories', 'admins', 'editors']
    
            for field in fcbkcomplete_fields:
                self.fields[field].widget = FCBKcompleteWidget()
    

    以下是我的模型:

    class Category(models.Model):
        """A blog category"""
    
        title = models.CharField(max_length=128)
        slug = models.SlugField()
    
        class Meta(object):
            verbose_name_plural = u'Categories'
    
        def __unicode__(self):
            return self.title
    
        @models.permalink
        def get_absolute_url(self):
            return ('category', (), {'slug': self.slug})
    
    
    class Blog(models.Model):
        """A blog"""
    
        title = models.CharField(max_length=128)
        slug = models.SlugField(unique=True)
        description = models.TextField()
        categories = models.ManyToManyField(Category, related_name='blogs')
        shared = models.BooleanField()
        admins = models.ManyToManyField(User, related_name='blog_admins')
        editors = models.ManyToManyField(User, related_name='blog_editors')
    
        def __unicode__(self):
            return self.title
    
        @models.permalink
        def get_absolute_url(self):
            return ('blog', (), {'slug': self.slug})
    

    以下是生成的HTML:

    <div class="field">
      <label for="name">Categories</label>
      <select multiple="multiple" name="categories" id="id_categories">
      </select>
      <div class="help-text">trimmed for readability</div>
    </div>
    <div class="field">
      <label for="name">Admins</label>
      <select multiple="multiple" name="admins" id="id_admins">
      </select>
      <div class="help-text">trimmed for readability</div>
    </div>
    <div class="field">
      <label for="name">Editors</label>
      <select multiple="multiple" name="editors" id="id_editors">
      </select>
      <div class="help-text">trimmed for readability</div>
    </div>
    

    正如您所看到的,没有一个选项可以将其添加到multiselect元素中。以下是我不使用自定义小部件替换小部件时生成的HTML:

    <div class="field">
      <label for="name">Categories</label>
      <select multiple="multiple" name="categories" id="id_categories">
        <option value="1" selected="selected">Good Stuff</option>
      </select>
      <div class="help-text">trimmed</div>
    </div>
    <div class="field">
      <label for="name">Admins</label>
      <select multiple="multiple" name="admins" id="id_admins">
        <option value="2" selected="selected">username</option>
        <option value="3">some username</option>
        <option value="4">another username</option>
      </select>
      <div class="help-text">trimmed</div>
    </div>
    <div class="field">
      <label for="name">Editors</label>
      <select multiple="multiple" name="editors" id="id_editors">
        <option value="2" selected="selected">username</option>
        <option value="3">some username</option>
        <option value="4">another username</option>
      </select>
      <div class="help-text">trimmed</div>
    </div>
    

    有没有人对为什么这些选项不能通过小部件更换过程提出任何建议?任何帮助都将不胜感激。

    1 回复  |  直到 16 年前
        1
  •  0
  •   Andrew    15 年前

    一年过去了,但即使使用当前的django版本,答案也可能很有价值。

    这种行为的原因似乎是fcbk字段缺少CHOICES属性 把选择推到表格上就行了

    class EmailSubscriptionFilterForm(forms.ModelForm):
    
        class Meta:
            model = EmailSubscription
            exclude = ('dsts',)
    
        def loc_name(self, id):
            return Location.objects.get(id = id).name           
    
        def __init__(self, *args, **kwargs):
            super(EmailSubscriptionFilterForm, self).__init__(*args, **kwargs)
            fcbkcomplete_fields = ['orgs']
            for field in fcbkcomplete_fields:
                self.fields[field].widget = MultiOriginSelect()
            if args:
                self.fields['orgs'].choices = ([(int(o), self.loc_name(int(o))) for o in args[0].getlist('orgs')] )
    

    对于init,它将把POST请求附带的所有选项添加到select body。