码迷,mamicode.com
首页 > 其他好文 > 详细

Django开发博客系统(07-根据需求定制管理后台)

时间:2020-04-01 16:20:18      阅读:97      评论:0      收藏:0      [点我收藏+]

标签:rgs   行编辑   name   hid   模块   定义   输入框   width   field   

运行系统尝试添加用户并添加数据,出现的效果

技术图片

 

 

 

可以看到当前登录的用户虽然是DOCTOR,但依然可以看到其他用户的文章,而且过滤器上也展示了非当前用户创建的分类,显然这是一个需要我们解决的问题.

 

首先解决右侧过滤器的功能,这时需要自定义过滤器,这里贴上文档中的说明

技术图片

接下来我们就来编写自定义过滤器的代码:

技术图片
 1 class CategoryOwnerFilter(admin.SimpleListFilter):
 2     """自定义过滤器只展示当前用户分类"""
 3 
 4     title = 分类过滤器  # 标题
 5     parameter_name = owner_category  # 查询时URL参数的名字
 6 
 7     def lookups(self, request, model_admin):  # 返回要展示的内容和查询用的id
 8         return Category.objects.filter(owner=request.user).values_list(id, name)
 9 
10     def queryset(self, request, queryset):
11         category_id = self.value()
12         if category_id:
13             return queryset.filter(category_id=self.value())
14         return queryset
CategoryOwnerFilter

parameter_name是在查询时的URL的参数名,

技术图片

我们的过滤器可以通过这个参数来进行过滤.

lookups是我们展示在页面的内容,以及查询用的id

技术图片

比如我点击 DOCTOR的Django分类 时,那么就会调用queryset方法,self.value()就是我们lookups中设置的查询用的id,在这里我的分类的id是3,所以传进来的参数也是3.

在代码编写完成后,记得要把PostAdmin中的过滤器改为

1 list_filter = [CategoryOwnerFilter]  # 页面过滤器

 

 

自定义列表页数据

 

接下来我们要让登录的用户在列表页中只能看到自己创建的文章.

我们需要重写get_queryset方法(我在文档中没有找到这一项的说明,但不管怎样,看它的名字我们就知道它返回的是一个QuerySet对象,那么我们就可以使用filter来进行过滤!这样就可以实现我们想要的效果了.)

1 def get_queryset(self, request):
2     qs = super(PostAdmin, self).get_queryset(request)
3     return qs.filter(owner=request.user)

技术图片

 

 

 

接下来进行编辑页面的配置.

首先我们得明确在编辑页面中有哪些东西是可以被定制的,比如:

l  按钮位置

l  哪些字段需要被用户填写,哪些不用填写甚至不用展示

l  页面的字段展示顺序是不是能被调整,展示位置是否能被调整

l  输入框的样式

按钮的位置用 save_on_top来控制是否在页面顶部展示按钮

对于字段是否展示以及展示顺序,可以通过fields或者fieldsets来配置

1 fields = (
2     (category, title),
3     desc,
4     status,
5     content,
6     tag,
7 )

技术图片

再试试用fieldsets替换fields:

fieldsets的格式要求有两个元素的tuple的list,例如

1 fieldsets = (
2     (名称, {内容}),
3     (名称, {内容}),
4 )

修改后的fieldsets;

技术图片
 1 fieldsets = (
 2     (基础配置, {
 3         description: 基础配置描述,
 4         fields: (
 5             (title, category),
 6             status,
 7         ),
 8     }),
 9     (内容, {
10         description: 摘要默认选取内容中的前140个字,
11         fields: (
12             desc,
13             content,
14         ),
15     }),
16     (额外信息, {
17         classes: (collapse, ),
18         fields: (tag, ),
19     }),
20 )
fieldsets

 

页面效果:

技术图片

fields的配置效果就跟原本的fields效果是一样的.

classes的作用是给要配置的板块加上一些CSS属性,Django admin默认支持collapse和wide.

description显然是板块的描述.

 

自定义静态资源引入

Django给我们提供了接口来添加css和js:

1 class Media:
2     css = {
3     all: ("https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css", ),
4 }
5 js = ("https://cdn.bootcss.com/twitter-bootstrap/4.4.0/js/bootstrap.bundle.js", )

 

 

自定义Form

以上的配置都是基于ModelAdmin的,如果我们有更多的定制需求,应该使用ModelForm,在blogApp中新建一个adminforms.py文件,我们要定制desc这个字段的展示,可以这样写

1 from django import forms
2 
3 
4 class PostAdminForm(forms.ModelForm):
5     desc = forms.CharField(widget=forms.Textarea, label=摘要, required=False)

配置到PostAdmin中

1 form = PostAdminForm

可以看到摘要已经改为Textarea组件了

技术图片

 

 

 

定制site

我们可以通过定制site来实现一个系统对外提供多套admin后台的逻辑.在我们原本的页面中,文章分类等数据的管理与用户管理是在一起的,这样看着其实挺别扭,对于功能上来说也不合适,所以我们来把它们分开.

我们之前使用的django提供的admin.site模块,这里面的site其实是django.contrib.admin.AdminSite的一个实例,我们通过继承来定义自己的site,代码如下:

 1 from django.contrib.admin import AdminSite
 2 
 3 
 4 class CustomSite(AdminSite):
 5     site_title = Blog管理后台
 6     site_header = Blog
 7     index_title = 首页
 8 
 9 
10 custom_site = CustomSite(name=cus_admin)

在Blog目录下新建一个custom_site.py文件,把代码贴上去,接下来修改所有App的admin中的register.

1 @admin.register(Category, site=custom_site)

在我们的PostAdmin中,我们自定义了一个operator方法,因为把site模块改为了自定义的模块,所以reverse中的名称也需要修改

1 def operator(self, obj):
2     return format_html(
3         <a href="{}">编辑</a>,
4         reverse(cus_admin:blogApp_post_change, args=(obj.id,))
5     )

最后在urls.py中添加路由

1 urlpatterns = [
2     path(admin/, custom_site.urls),
3     path(super_admin/, admin.site.urls),
4 ]

 

这样就有了两套后台地址.要注意的是这两套系统都是基于一套逻辑的用户系统,只是我们在URL上进行了划分.

 

抽取Admin基类

在我们的admin中,我们重写了save_model方法和get_queryset方法,这就让我们的代码有很多重复,质量很差,可以通过继承来使代码变得简洁.

抽象出一个基类BaseOwnerAdmin

 1 from django.contrib import admin
 2 
 3 
 4 class BaseOwnerAdmin(admin.ModelAdmin):
 5     exclude = (owner, )
 6 
 7     def get_queryset(self, request):
 8         qs = super(BaseOwnerAdmin, self).get_queryset(request)
 9         return qs.filter(owner=request.user)
10 
11     def save_model(self, request, obj, form, change):
12         obj.owner = request.user
13         return super(BaseOwnerAdmin, self).save_model(request, obj, form, change)

把它放到Blog目录下的base_admin.py文件中,把App的admin中的继承改为BaseOwnerAdmin即可.

 

最后还有添加查看操作日志功能.

1 @admin.register(LogEntry, site=custom_site)
2 class LogEntryAdmin(admin.ModelAdmin):
3     list_display = [object_repr, object_id, action_flag, user, change_message]

 

 

之后开始开发面向用户的界面.

Django开发博客系统(07-根据需求定制管理后台)

标签:rgs   行编辑   name   hid   模块   定义   输入框   width   field   

原文地址:https://www.cnblogs.com/ylnx-tl/p/12613263.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!