Django开发博客系统(11-使用xadmin)

Posted ylnx-tl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django开发博客系统(11-使用xadmin)相关的知识,希望对你有一定的参考价值。

这段时间进行了前端页面的美化,实现了搜索功能与评论功能,以及配置了rss和sitemap,不过这些东西后期可能还会进行大改,所以暂时不准备讲,可能完成之后会一起说一下...吧.

另外这里贴上我的源码,不过还没有完成,有兴趣可以去看看.

 

今天将后台的admin替换为了xadmin,xadmin是国人创建的一个开源项目,作者github,这个项目简单来说可以完全无痛地替换admin,同时增加很多有用的功能,界面也是基于Bootstrap,相较自带的更美观.

先来看看最终完成的效果图吧

技术图片

 

 

 接下来就进行xadmin的配置.

 

安装

pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2

在base.py中配置INSTALLED_APPS

1 INSTALLED_APPS = [
2     ...
3     xadmin,
4     crispy_forms,
5     reversion,
6     ...
7 ]

接下来尝试创建迁移,会报一连串的错误,接下来一个个解决.

我的开发环境是:python3.8.0 + django3.0.4

 

1.ImportError: cannot import name ‘six‘ from ‘django.utils‘

技术图片

 找到six.py所在的位置并复制这个文件

技术图片

 把six.py复制到‘django.utils‘所在的路径

 

2.cannot import name ‘python_2_unicode_compatible‘ from ‘django.utils.encoding‘

技术图片

找到路径中的models.py,把第十一行的

from django.utils.encoding import python_2_unicode_compatible, smart_text

 

替换为

1 from django.utils.encoding import smart_text
2 from six import python_2_unicode_compatible

 

 

3.ModuleNotFoundError: No module named ‘django.contrib.staticfiles.templatetags‘

找到util.py

技术图片

找到这一行,将其替换为

from django.templatetags.static import static

 

执行迁移..

 

开始配置xadmin

 

1.在各个App中新建adminx.py文件,并把对应的admin.py中的内容复制过去

技术图片

 

2.将我们定义的ModelAdmin的继承对象改为object或者去掉继承,这里我选择新建一个base_xadmin.py文件,内容与base_admin.py相同,只是把

class BaseOwnerAdmin(admin.ModelAdmin):
# 改为
class BaseOwnerAdmin:

有几个类是直接继承admin.ModelAdmin的,也需要去掉继承.

 

3.修改类中的内容

把fieldsets修改为Fieldsets

用PostAdmin来举例

技术图片
 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: (wide, ),
18         fields: (tag, ),
19     }),
20 )

改为

技术图片
 1 form_layout = (
 2     Fieldset(
 3         基础信息,
 4         Row(title, category),
 5         status,
 6         tag,
 7     ),
 8     Fieldset(
 9         内容信息,
10         desc,
11         content,
12     )
13 )

 

自定义过滤器修改

之前我们在post中自定义了一个按照分类过滤的过滤器

 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

 

xadmin:

 1 class CategoryOwnerFilter(RelatedFieldListFilter):
 2     """自定义过滤器只展示当前用户分类"""
 3 
 4     @classmethod
 5     def test(cls, field, request, params, model, admin_view, field_path):
 6         return field.name == category
 7 
 8     def __init__(self, field, request, params, model, model_admin, field_path):
 9         super(CategoryOwnerFilter, self).__init__(field, request, params, model, model_admin, field_path)
10         # 重新获取lookup_choices, 根据owner过滤
11         self.lookup_choices = Category.objects.filter(owner=request.user).values_list(id, name)

 

同时PostAdmin中也需要修改:

list_filter = [CategoryOwnerFilter]  # 页面过滤器

# 改为

list_filter = [category]  # 页面过滤器

其中,test方法的作用是确认字段是否需要被当前的过滤器过滤.

在__init__方法中,我们执行完父类的__init__后,重新定义了lookup_choices的值,这个值默认是查询所有数据.

 

操作配置

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

 

改为

1 def operator(self, obj):
2     return format_html(
3         <a href="{}">编辑</a>,
4         self.model_admin_url(change, obj.id)
5     )
6 operator.short_description = 操作

 

装饰器

@admin.register(Post, site=custom_site)

改为

@xadmin.sites.register(Post)

 

其他修改与Post类似

添加路由

path(xadmin/, xadmin.site.urls, name=xadmin),

 

 

这时使用的时候发现又能看到其他用户的文章了,这是因为接口存在差异,BaseOwnerAdmin中的

1 def get_queryset(self, request):
2     qs = super(BaseOwnerAdmin, self).get_queryset(request)
3     return qs.filter(owner=request.user)
4 
5 def save_model(self, request, obj, form, change):
6     obj.owner = request.user
7     return super(BaseOwnerAdmin, self).save_model(request, obj, form, change)

需要改为

1 def get_list_queryset(self):
2     request = self.request
3     qs = super().get_list_queryset()
4     return qs.filter(owner=request.user)
5 
6 def save_models(self):
7     self.new_obj.owner = self.request.user
8     return super().save_model()

 

另外在在xadmin中,我们可以在settings中来自定义系统名称和footer需要展示的内容.

settings/base.py

1 XADMIN_TITLE = Blog管理后台
2 XADMIN_FOOTER_TITLE = power by ylnx2000.cn

xadmin也自带了log功能,所以我们可以删掉LogEntryAdmin.

xadmin还有很多功能,想要熟悉的话最好还是通过手册与阅读源码来了解

 

另外我在使用xadmin时,

1 # @property
2     # def media(self):
3     #     media = super().media
4     #     media.add_js([‘https://cdn.bootcss.com/twitter-bootstrap/4.4.0/js/bootstrap.bundle.js‘])
5     #     media.add_css({
6     #         ‘all‘: (‘https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css‘,),
7     #     })
8     #     return media

在PostAdmin中使用静态资源会出现

 技术图片

 

 在百度中是说需要替换util.py中的内容,但我发现那里面

技术图片

 

 内容没错,所以报错的原因似乎不一样,这里我还没有解决,希望能得到解答.

技术图片

 

以上是关于Django开发博客系统(11-使用xadmin)的主要内容,如果未能解决你的问题,请参考以下文章

django2.1.5使用xadmin打造适合国人的后台管理系统

python测试开发django-55.xadmin使用markdown文档编辑器(django-mdeditor)

django后台管理系统xadmin

django 1.11.1版本使用xadmin

Django+xadmin打造在线教育平台

Python升级3.6 强力Django+杀手级Xadmin打造在线教育平台