Django中Many2ManyField大记录集选择的解决方案


Django中ManyToManyField和ForeignKey字段关联到另外一个Model,如:

 

   class Article(models.Model): 
          RelateArticles=models.ManyToManyField('self',verbose_name=u'相关文章',blank=True,null=True)

在admin的管理界面中默认是这样的选取输入方式:




大部分情况下,这个输入界面是可以满足要求的。

以上例来说,如果Article包含的记录数非常多,就很悲剧了,Django默认并没有进行特殊的处理

所有的关联记录都会被传送到浏览器进行显示,这会造成前端浏览器的假死。


Django也预见了这种情况,因此给出了这样的解决方案:

class ArticleAdmin(ModelAdmin):
          raw_id_fields = ("RelateArticles",)

将可能关联到大量记录的字段设置到admin的raw_id_fields元组中,于是,在admin界面中的输入界面就变成这样:


Django中Many2ManyField大记录集选择的解决方案_第1张图片

需要手工删除编辑关联项的pk,或者点击图标进行选择。

但是这种方式我觉得体验不是很好,因此自己写了一个django form/field/widget 组件来实现,效果如这样:

Django中Many2ManyField大记录集选择的解决方案_第2张图片

在右侧搜索框输入关键字,然后发起AJAX,在后端进行查询并返回结果供选择。

使用方法如这样:

class ArticleAdminForm(OneModelForm):
    RelateArticles=SearchForSelectField(searchField="Title")
    class Meta:
        model=Article

先定义一个管理表单,继承自OneModelForm,然后将要设定这个组件的字段和Model.

searchField="Title"代表要在Title字段进行搜索。

然后在class ArticleAdmin(ModelAdmin)里面加入一条:

class ArticleAdmin(ModelAdmin):
    form=ArticleAdminForm

在Article Model里面加入一个方法

class Article(models.Model):
    ID=models.AutoField(u'序号',primary_key=True)
    Title=models.CharField(u'标题',max_length=64,blank=False) 
    ......
    @classmethod
    def search_field(cls,field_name,keyword):
        try:
            return list(Article.objects.filter(**{field_name+"__icontains":keyword}).values_list("pk",field_name))
        except:
            return []


最后还要设置一个URL,像这样:

url(r'^oneform/',include('utils.OneForm.urls' ))

OK,大功告成!


注:这个widget近期发布,请关注。







你可能感兴趣的:(Django中Many2ManyField大记录集选择的解决方案)