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界面中的输入界面就变成这样:
需要手工删除编辑关联项的pk,或者点击图标进行选择。
但是这种方式我觉得体验不是很好,因此自己写了一个django form/field/widget 组件来实现,效果如这样:
在右侧搜索框输入关键字,然后发起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近期发布,请关注。