Django Admin 实现外键过滤的方法
说明和Model
环境:
➜python Python3.6.3|Anacondacustom(x86_64)|(default,Oct62017,12:04:38) [GCC4.2.1CompatibleClang4.0.1(tags/RELEASE_401/final)]ondarwin Type"help","copyright","credits"or"license"formoreinformation. >>>importdjango >>>print(django.get_version()) 2.0.1 >>>
2018年05月23日更新:
可以通过get_changeform_initial_data函数来传递initial参数.
#admin.py @admin.register(Score) classScoreConfigAdmin(FilterUserAdmin): #fields=('id','name') form=ScoreConfigAdminForm defget_changeform_initial_data(self,request): initial=super().get_changeform_initial_data(request) initial.update({'uid':request.user.id}) returninitial #forms.py classScoreConfigAdminForm(forms.ModelForm): def__init__(self,*args,**kwargs): super().__init__(*args,**kwargs) ifnotkwargs.get('initial'): return self.uid=kwargs.get('initial').get('uid') classMeta: model=Score fields='__all__'
有一个支持多用户(使用djangoadmin)的Blog,每一篇Post都需要记录是谁发表的并且属于那个Blog。
user与Blog的关系、Blog与Post有2种定义方式,一种是使用独立关系表,另外一种是直接在Model中定义中使用外键。
后面一种的model定义如下:
fromdjango.contrib.auth.modelsimportUser fromdjango.dbimportmodels classBlog(models.Model): ''' Blog ''' id=models.AutoField(unique=True,primary_key=True,verbose_name="序号") name=models.CharField(max_length=255,blank=True,null=True,verbose_name="名称") user=models.ForeignKey(User,on_delete=models.CASCADE) create_time=models.DateTimeField(verbose_name='添加时间',auto_now_add=True,blank=True) classMeta: verbose_name='Blog' verbose_name_plural='Blog管理' def__str__(self): returnself.name classPost(models.Model): ''' Post内容 ''' id=models.AutoField(unique=True,primary_key=True,verbose_name="序号") title=models.CharField(max_length=255,blank=True,null=True,verbose_name="标题") content=models.TextField(max_length=1024,blank=True,null=True,verbose_name="内容") blog=models.ForeignKey(Blog,on_delete=models.CASCADE,verbose_name="所属Blog") user=models.ForeignKey(User,on_delete=models.CASCADE) create_time=models.DateTimeField(verbose_name='添加时间',auto_now_add=True,blank=True) classMeta: verbose_name='文章' verbose_name_plural='文章管理' def__str__(self): returnself.title
Admin中实现
admin中有2处,一处是Blog和Post列表中按user过滤,另外一处是新增Post时需要按当前user过滤。完整代码如下:
fromdjango.contribimportadmin fromdjangoimportforms #Registeryourmodelshere. fromdjango_summernote.adminimportSummernoteModelAdmin from.modelsimportTeam,Member,Activity,Score from.modelsimportBlog,Post classFilterUserAdmin(admin.ModelAdmin): ''' 按所属用户过滤的base,class ''' defsave_model(self,request,obj,form,change): #TODO需要考虑不同用户对同一数据进行修改。 obj.user=request.user obj.save() defget_queryset(self,request): #ForDjango<1.6,overridequerysetinsteadofget_queryset qs=super(FilterUserAdmin,self).get_queryset(request) #不能加这个,加了这个会导致superuser更新普通用户的数据。 #ifrequest.user.is_superuser: #returnqs returnqs.filter(user=request.user) defhas_change_permission(self,request,obj=None): has_class_permission=super(FilterUserAdmin,self).has_change_permission(request,obj) ifnothas_class_permission: returnFalse ifobjisnotNoneandnotrequest.user.is_superuserandrequest.user.id!=obj.user.id: returnFalse returnTrue classBlogConfigAdmin(FilterUserAdmin): list_display=('id','name','create_time') exclude=['user'] list_per_page=50 admin.site.register(Blog,BlogConfigAdmin) classPostConfigAdmin(FilterUserAdmin): list_display=('id','title','create_time') exclude=['user'] list_per_page=50 defrender_change_form(self,request,context,add=False,change=False,form_url='',obj=None): #新增Post时,相关联的Blog需要过滤,关键就在下面这句。 context['adminform'].form.fields['blog'].queryset=Team.objects.filter(user=request.user) returnsuper(MemberConfigAdmin,self).render_change_form(request,context,add,change,form_url,obj) admin.site.register(Post,PostConfigAdmin)
说2句
在render_change_form中下断点,直接调试下会发现更多有趣的内容。
以上这篇DjangoAdmin实现外键过滤的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。