澳门新浦京app下载帝国CMS 将TAGS放到的方法

澳门新浦京app下载 19

帝国cms在 新增/编辑
信息时,信息的TAGS属性隐藏于选项卡中,如果将TAGS放到选项卡中,则可以省时省力又方便管理。如图:

cms 通过内容模型功能实现了在后台即可管理文章数据表的功能。内容模型是一个
cms 最基本的功能。

admin自定义配置

实现此功能分两步修改:

每个内容模型对应一张数据表,添加一个内容模型就会添加一张数据表,删除一个内容模型就会删除一张数据表。

一、admin.py

我们知道在models.py文件中创建的数据表,一方面我们可以通过视图函数对其进行增删改查,一方面我们也可以通过admin进行,通常我们是通过admin的前端页面进行增删改查。这里我们在后端admin.py文件中进行。

1、修改 e/admin/AddNews.php 文件

模型与数据表的对应规则是:数据表名=表前序 + c_ + 模型定义的表名。
澳门新浦京app下载 1

1.admin.site.register

用admin对数据表的操作都需要在每个APP项目中的admin.py文件中将你需要处理的表名admin.site.register(表名)导入

澳门新浦京app下载 2

创建OK后现在进入admin的页面进行操作:

澳门新浦京app下载 3

在此文件中查找 td height=25 bgcolor=#FFFFFFTAGS
,在此处上下行代码找到如下代码并删除:

对应的数据表就是 phpcms2008_c_jieju

2.admin的增删改查的url规律:

通过admin对UserInfo表进行增删改查可知其url的变化的规律如下所示:

     自动生成URL
        /admin/app01/userinfo/                  列表 change_list_view
        /admin/app01/userinfo/add/              增加 方法
        /admin/app01/userinfo/2/change/         修改 方法
        /admin/app01/userinfo/2/delete/         删除 方法

执行到这一步我们会有疑问,如此多的url,而在Django的url的配置文件中却只有下面这行代码:

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

这里我们猜想在执行路由分发之前url(r’^admin/’,
admin.site.urls),它一定先做了什么事。

 ?php if(strstr($public_r[usetags],,.$modid.,)) { $infotag_readonly=;$infotag_copykeyboard=input type=button name=Submit3 value=复制关键字 onclick=document.add.infotags.value=document.add.keyboard.value;; if(strstr($public_r[chtags],,.$modid.,)){$infotag_readonly= readonly;$infotag_copykeyboard=;} ? tr td height=25 bgcolor=#FFFFFFTAGS: input name=infotags type=text id=infotags value=?=$r[infotags]? size=32?=$infotag_readonly? input type=button name=Submit value=选择 onclick=window.open(tags/ChangeTags.php?form=addfield=infotags?=$ecms_hashur[ehref]?,,width=700,height=550,scrollbars=yes); ?=$infotag_copykeyboard? input name=oldinfotags type=hidden id=oldinfotags value=?=$r[infotags]? font color=#333333(多个用,逗号格开)/font/td /tr ?php } ?

在后台可以管理模型数据:
澳门新浦京app下载 4
模型信息保存在 model 表中(eg. phpcms2008_model)

3.admin中的配置方法

1.单字段显示字段文本名:

class UserInfo(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField(max_length=32)
    def __str__(self):
        return self.name

效果如下图所示:

澳门新浦京app下载 5

2.多字段文本显示:

admin在__str__的默认方式中提供的只有单字段的文本显示,但是通过admin.py文件我们可以自定义多字段的文本显示如下:

from django.contrib import admin
from . import models

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email']     #list_display即在admin的页面中显示的字段
admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法

执行后的效果如下图所示:

澳门新浦京app下载 6

这里我们需要注意的是list_display这个列表中的字段既可以是数据表中既有的字段也可以是自定义的字段,如下代码即可实现:

from django.contrib import admin
from . import models

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email','whatmini']     #list_display即在admin的页面中显示的字段

    def whatmini(self,obj):     #自定义显示的字段

        return "hello"

admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法

执行的效果如下图所示:

澳门新浦京app下载 7

当需要自定义字段显示时,需要创建以显示字段为函数名的函数,并带有return值的函数,上述whatmini代码中的另一个参数obj,是当前数据对象
如下将代码修改执行:

def whatmini(self,obj):     #自定义显示的字段
    print(obj)
    return obj.name

下面是执行的结果

October 18, 2017 - 16:48:24
Django version 1.11.4, using settings 'lijianCrm.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
UserInfo object
UserInfo object

下面是前端admin页面的显示效果:

澳门新浦京app下载 8

所以通过这个自定义的我们可以做很多的事情如可以将字段变成a标签:

from django.contrib import admin
from . import models
from django.utils.safestring import mark_safe

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email','whatmini']     #list_display即在admin的页面中显示的字段

    def whatmini(self,obj):     #自定义显示的字段
        tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name)
        return mark_safe(tp1)

admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法

admin前端页面显示效果如下:

澳门新浦京app下载 9

需要了解的是,admin.ModelAdmin是admin对每个数据表执行的一个默认的配置,其源码如下

register源码

澳门新浦京app下载 10

通过register的源码可以知道 model_or_iterable这个参数可以是列表

 def register(self, model_or_iterable, admin_class=None, **options):
    """
    Registers the given model(s) with the given admin class.

    The model(s) should be Model classes, not instances.

    If an admin class isn't given, it will use ModelAdmin (the default
    admin options). If keyword arguments are given -- e.g., list_display --
    they'll be applied as options to the admin class.

    If a model is already registered, this will raise AlreadyRegistered.

    If a model is abstract, this will raise ImproperlyConfigured.
    """
    if not admin_class:
        admin_class = ModelAdmin

    if isinstance(model_or_iterable, ModelBase):  #当model_or_iterable 是列表时执行下面代码
        model_or_iterable = [model_or_iterable]

即可以在admin.py中的代码可以改成下面操作:

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email','whatmini']     #list_display即在admin的页面中显示的字段

    def whatmini(self,obj):     #自定义显示的字段
        tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name)
        return mark_safe(tp1)

admin.site.register([models.UserInfo,"第二张表","第三张表",....],foo)    #表示在admin在处理UserInfo中执行foo中的方法

这里三张表都可以执行foo函数的方法。

同时也可以通过装饰器的方式进行:

from django.contrib import admin
from . import models
from django.utils.safestring import mark_safe

@admin.register(models.UserInfo)
class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email','whatmini']     #list_display即在admin的页面中显示的字段

    def whatmini(self,obj):     #自定义显示的字段
        tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name)
        return mark_safe(tp1)

ModelAdmin源码:

澳门新浦京app下载 11

3.list_display_links方法:

list_display_links,列表时,定制列可以点击跳转。

from django.contrib import admin
from . import models
from django.utils.safestring import mark_safe

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email']     #list_display即在admin的页面中显示的字段
    list_display_links = ['name','email']


admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法

4.list_filter,列表时,定制右侧快速筛选

from django.contrib import admin
from . import models
from django.utils.safestring import mark_safe

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email']     #list_display即在admin的页面中显示的字段
    list_display_links = ['name','email']
    list_filter = ['name','group']  

admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法
admin.site.register(models.UserGroup)

当这里的UserInfo和第三张表进行ForeignKey关联时也会将第三张表的数据显示如下:

澳门新浦京app下载 12

也可以通过下面的代码进行定制:

from django.contrib import admin
from . import models
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email']     #list_display即在admin的页面中显示的字段
    list_display_links = ['name','email']


    class Ugg(admin.SimpleListFilter):
        title = _('角色组')
        parameter_name = 'xxxxxx'

        def lookups(self, request, model_admin):
            """
            显示筛选选项
            :param request:
            :param model_admin:
            :return:
            """
            return models.UserGroup.objects.values_list('id', 'title')   #前端显示的筛选条件

        def queryset(self, request, queryset):
            """
            点击查询时,进行筛选
            :param request:
            :param queryset:
            :return:
            """
            v = self.value()
            return queryset


    list_filter = ['name',Ugg]


admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法

admin.site.register(models.UserGroup)

5.list_select_related,列表时,连表查询是否自动select_related

6.分页

# 分页,每页显示条数
    list_per_page = 100

# 分页,显示全部(真实数据<该值时,才会有显示全部)
    list_max_show_all = 200

# 分页插件
    paginator = Paginator

7.list_editable,列表时,可以编辑的列

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
        list_display = ('user', 'pwd','ug',)
        list_editable = ('ug',)

8.search_fields,列表时,模糊搜索的功能

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):

    search_fields = ('user', 'pwd')

9.date_hierarchy,列表时,对Date和DateTime类型进行搜索

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):

    date_hierarchy = 'ctime'

需要注意的是该方法需要数据表中有时间的字段

10.preserve_filters,详细页面,删除、修改,更新后跳转回列表后,是否保留原搜索条件

11.save_as = False,详细页面,按钮为“Sava as new” 或 “Sava and add
another”

12.save_as_continue = True,点击保存并继续编辑

save_as_continue = True

# 如果 save_as=True,save_as_continue = True, 点击Sava as new 按钮后继续编辑。
# 如果 save_as=True,save_as_continue = False,点击Sava as new 按钮后返回列表。

New in Django 1.10.

13.save_on_top = False,详细页面,在页面上方是否也显示保存删除等按钮

14.inlines,详细页面,如果有其他表和当前表做FK,那么详细页面可以进行动态增加和删除

class UserInfoInline(admin.StackedInline): # TabularInline这个也可以继承功能和StackedInline的功能一样只是显示方式不同而已
    extra = 0
    model = models.UserInfo
class UserGroupAdmin(admin.ModelAdmin):
    list_display = ['title',]
    inlines = [UserInfoInline, ]
admin.site.register(models.UserGroup,UserGroupAdmin)

admin前端页面的显示效果如下:

澳门新浦京app下载 13

这里需要注意的是,ForeignKey字段在在哪个表则上述代码只能关联另外的表不能关联FK字段所在的那张表

15.action,列表时,定制action中的操作

澳门新浦京app下载 14

代码如下:

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email']     #list_display即在admin的页面中显示的字段
    list_display_links = ['name','email']

    def func(self,request,queryset):
        pass
    actions = [func,]

所以这里通过func我们可以做自定义的操作如下:

澳门新浦京app下载 15

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email']     #list_display即在admin的页面中显示的字段
    list_display_links = ['name','email']

    def func(self,request,queryset):
        print(request.POST.getlist('_selected_action'))
        print('代码来了')
    actions = [func,]
    func.short_description = "中文显示自定义Actions"

执行结果:

[18/Oct/2017 19:26:58] "GET /static/admin/img/tooltag-add.svg HTTP/1.1" 304 0
['2', '1']
代码来了
[18/Oct/2017 19:27:08] "POST /admin/app01/userinfo/ HTTP/1.1" 302 0

16.定制HTML模板

change_list_template页面

澳门新浦京app下载 16

澳门新浦京app下载 17

除了change_list_template页面admin中还有以下页面:

add_form_template = None   #添加页面
change_form_template = None #编辑页面
delete_confirmation_template = None #删除页面
delete_selected_confirmation_template = None  #删除确认页面
object_history_template = None   #删除显示记录页面

17.raw_id_fields,详细页面,针对FK和M2M字段变成以Input框形式

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):

    raw_id_fields = ('FK字段', 'M2M字段',)

18.fields,详细页面时,显示字段的字段

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    fields = ('user',)

19.exclude,详细页面时,排除的字段

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    exclude = ('user',)

20.readonly_fields,详细页面时,只读字段

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    readonly_fields = ('user',)

21.fieldsets,详细页面时,使用fieldsets标签对数据进行分割显示

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
    fieldsets = (
        ('基本数据', {
            'fields': ('user', 'pwd', 'ctime',)
        }),
        ('其他', {
            'classes': ('collapse', 'wide', 'extrapretty'),  # 'collapse','wide', 'extrapretty'
            'fields': ('user', 'pwd'),
        }),
    )

22.详细页面时,M2M显示时,数据移动选择(方向:上下和左右)

澳门新浦京app下载 18

代码如下:

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email']     #list_display即在admin的页面中显示的字段
    list_display_links = ['name','email']

    def func(self,request,queryset):
        print(request.POST.getlist('_selected_action'))
        print('代码来了')
    actions = [func,]
    func.short_description = "中文显示自定义Actions"

    filter_horizontal = ("roles",)

这里需要注意关联数据表要有ManyToManyField的字段

23.ordering,列表时,数据排序规则

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    ordering = ('-id',)
    或
    def get_ordering(self, request):
        return ['-id', ]  #从小到大排

24.view_on_site,编辑时,是否在页面上显示view on set

class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
    list_display = ['name','email']     #list_display即在admin的页面中显示的字段
    list_display_links = ['name','email']

    def func(self,request,queryset):
        print(request.POST.getlist('_selected_action'))
        print('代码来了')
    actions = [func,]
    func.short_description = "中文显示自定义Actions"

    filter_horizontal = ("roles",)

    def view_on_site(self,obj):
        return 'https://www.baidu.com'

澳门新浦京app下载 19

25.radio_fields,详细页面时,使用radio显示选项(FK默认使用select)

radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL

26.show_full_result_count =
True,列表时,模糊搜索后面显示的数据个数样式

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    # show_full_result_count = True # 1 result (12 total)
    # show_full_result_count = False  # 1 result (Show all)
    search_fields = ('user',)

27.formfield_overrides = {},详细页面时,指定现实插件

from django.forms import widgets
from django.utils.html import format_html

class MyTextarea(widgets.Widget):
    def __init__(self, attrs=None):
        # Use slightly better defaults than HTML's 20x2 box
        default_attrs = {'cols': '40', 'rows': '10'}
        if attrs:
            default_attrs.update(attrs)
        super(MyTextarea, self).__init__(default_attrs)

    def render(self, name, value, attrs=None):
        if value is None:
            value = ''
        final_attrs = self.build_attrs(attrs, name=name)
        return format_html('<textarea {}>rn{}</textarea>',final_attrs, value)



@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):

    formfield_overrides = {
        models.models.CharField: {'widget': MyTextarea},
    }

28.prepopulated_fields =
{},添加页面,当在某字段填入值后,自动会将值填充到指定字段。

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):

    prepopulated_fields = {"email": ("user","pwd",)}

29.form = ModelForm,用于定制用户请求时候表单验证

from app01 import models
from django.forms import ModelForm
from django.forms import fields


class MyForm(ModelForm):
    others = fields.CharField()

    class Meta:
        model = models = models.UserInfo
        fields = "__all__"

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):

    form = MyForm 

30.empty_value_display = “列数据为空时,显示默认值”

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
    empty_value_display = "列数据为空时,默认显示"

    list_display = ('user','pwd','up')

    def up(self,obj):
        return obj.user
    up.empty_value_display = "指定列数据为空时,默认显示"

2、修改各数据表的 special.field 字段

每个模型都有一组相同的字段,称为[系统字段]:
澳门新浦京app下载 20
在添加模型时会自动加入系统字段,系统字段不能删除,只能禁用。

special.field 是系统默认字段,在字段的“输入表单替换html代码”中末尾,找到
/table ,在其上插入第一步中删除的代码即可。

添加模型的操作通过 /admin/model.inc.php 中的 add
部份实现,真正处理的代码是 /include/admin/model.class.php 的 add()
方法。
通过执行 /include/admin/model.sql 中的 SQL 语句建立模型对应的数据表。

注意:所有需使用tag功能的数据表都需要做第二步的修改。

新建立的模型对应的数据表只有 contentid, content, template 三个字段,除
contentid 外,并没有如 catid, title 这类模型[系统字段]。

这些系统字段放在 content 表中(eg. phpcms2008_content),这个表有
contentid, catid, title, url, thumb 等这些基本的文章字段。

所有模型中的文章的 url, title, thumb 等数据都是保存在 content
表中的,除这些字段外的字段值才保存在对应的模型数据表中,比如 content
字段就保存在模型数据表。

在添加一篇文章时,先把由 content 表保存的数据插入 content 表,取回插入的
contentid, 就是数据库的 insert_id ,再把其它字段值插入模型数据表中,
content 表称为主表,模型数据表称为扩展表,主表与扩展表通过 contentid
关联。

这种结构有以下几个特点:

  1. 所有模型中的文章都可以使用一个连续的 contentid
    ,因此主表的一个作用就是产生一个自动编号的 contentid 。
    2.
    通过一个主表就可以查询到所有的文章数据,实现前台不同栏目不同模型的数据整合显示。
    3.
    从数据库优化的角度,一个数据表若要查询速度快,尽量使用定长的字段类型(eg.
    char),避免使用变长的字段类型(eg. varchar,
    text),因此把所有变长的字段(eg.
    content)都放在扩展表中,令主表所有字段都是定长字段类型,加快查询速度。

一个模型的字段信息保存在 model_field 表中(eg.
phpcms2008_model_field),系统字段每一个对应主表中的一个字段,所以才会不能删除,其它字段每一个对应扩展表中的一个字段。

如 content 字段:

澳门新浦京app下载 21

虽是在新建模型时建立的字段,但并非系统字段,对应的是扩展表中的 content
字段。

在给一个模型添加字段时,所添加的都是扩展表的字段。添加字段的操作由
/admin/model_field.inc.php 中的 add 部份执行。在使用
/include/admin/model_field.class.php 的 add() 方法把字段数据保存到
model_field 表后,会调用对应字段类型的 field_add.inc.php
文件为扩展表增加实际的数据表字段。

字段类型是对数据表字段的一种包装,cms 的所有字段类型存放于
/include/fields/
目录下,每个字段类型一个文件夹,文件夹名就是字段类型名。

每个字段类型的中文含意保存在 /include/fields/fields.inc.php 文件中。

在后台添加模型字段时,会调用对应字段类型的 field_add.inc.php
文件,此文件的作用就是为扩展表添加字段。

以 editor 字段类型为例, editor 字段类型的中文含意是[编辑器],可以在
/include/fields/fields.inc.php 中查到,字段类型目录是
/include/fields/editor/ 。

字段类型可以有自己的设置参数,使用 field_add_form.inc.php 文件,editor
字段类型的设置参数表单文件就是
/include/fields/editor/field_add_form.inc.php :

澳门新浦京app下载 22

另一个相似的文件是 field_edit_form.inc.php ,在修改字段时使用。

editor 字段类型实际使用 MySQL 的 MEDIUMTEXT
字段类型保存。在添加模型字段时,会调用字段类型的 field_add.inc.php
文件,其作用就是为扩展表添加实际的表字段, editor 字段类型的
/include/fields/editor/field_add.inc.php 文件就是给扩展表加上一个
MEDIUMTEXT 字段。

与 field_add.inc.php 功能相似的是 field_edit.inc.php
文件,在修改模型字段时调用,用于修改扩展表的字段。

在定义好模型及模型字段后,就可以使用模型录入数据了。cms
采用的是栏目关联模型,要使用模型需要先建立与此模型关联的栏目:
澳门新浦京app下载 23
建好栏目后,就可以在[内容管理]菜单中打开对应的栏目,点击[发布],便可见到文章录入表单:

澳门新浦京app下载 24

澳门新浦京app下载 25

澳门新浦京app下载 26

录入表单由对应的字段类型自己负责生成,比如 editor 字段类型的表单是一个
HTML 编辑器,由 editor 自己负责生成:
澳门新浦京app下载 27
生成录入表单调用的是 /include/content_form.class.php
文件,里面是所有字段类型生成其表单的方法,比如 editor() 方法就是生成
editor 字段类型的录入表单。

录入文章的后台控制器是 /admin/content.inc.php 文件 add
部份。生成各字段的录入表单是这三句 PHP 代码:
require PHPCMS_ROOT .’include/content_form.class.php’;
$content_form = new content_form($modelid);
$forminfos = $content_form->get($data);

修改文章时也是用同样的逻辑生成数据编辑表单。

表单提交数据后,会使用 /include/admin/content.class.php 的 add()
方法把数据保存到数据表中,在写入数据表之前,会先调用
/include/content_input.class.php 的 get()
方法对表单提交的数据进行处理,并按主表及扩展表的字段分成两个数据。之后先插入主表,再插入扩展表。
在插入完数据后再调用 /include/content_update.class.php 的 update()
方法。进行插入数据后的后续操作。

content_input.class.php 主要让字段类型对输入的数据进行格式化操作,比如
int 类的表字段在 php 中使用 intval 格式化一下,不允许 html 的文本框使用
html 过滤函数过滤一下,文件上传形的字段类型处理上传的文件等。

content_update.class.php 主要用于执行需要得到 contentid
后才能进行的操作。

这样,便能为模型录入数据了。

至于前台查询(主要是首页,列表页这种页面),主要是从主表中查询,需要用到扩展表字段时则使用
join 连表查询。采用直接写 sql 语句的形式。
前台查询最常见的就是显示某一栏目的文章,所以主表会根据前台主要的查询建立索引。比如给
catid 加索引,在 where 时走索引,给 listorder, updatetime 这些加索引,在
order by 时走索引。

在前台显示一篇文章时,使调用 /include/content_output.class.php
对字段值进行输出前的加工处理。字段类型需要输出前的格式化都可以在这里完成。

版权声明:本文为博主原创文章,未经博主允许不得转载。


You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图