day21 stark组件开发之为页面提供自定义显示列函数

自定义显示列函数

在列表中新增自定义列,比如“编辑”和“删除”按钮

1、首先基类模块导入函数

from django.urls import reverse
from django.utils.safestring import mark_safe
from types import FunctionType

2、在基类中新增自定义函数

   def display_edit(self, obj=None, is_header=None):
        """
        自定义页面显示的列(表头和内容)
        :param obj:
        :param is_header:
        :return:
        """
        if is_header:
            return "编辑"
        name = "%s:%s" % (self.site.namespace, self.get_change_url_name,)
        return mark_safe('<a href="%s">编辑</a>' % reverse(name, args=(obj.pk,)))

    def display_del(self, obj=None, is_header=None):
        if is_header:
            return "删除"
        name = "%s:%s" % (self.site.namespace, self.get_delete_url_name,)
        return mark_safe('<a href="%s">删除</a>' % reverse(name, args=(obj.pk,)))

3、stark组件中调用方式

    list_display = ['id', 'title', StarkHandler.display_edit, StarkHandler.display_del]

扩展:点击编辑或删除按钮时需要有跳转链接,再此优化自定义链接

1、基类模块中自启动函数需要新增字段

2、新增自定义链接函数

   def get_url_name(self, param):
        app_label, model_name = self.model_class._meta.app_label, self.model_class._meta.model_name
        if self.prev:
            return '%s_%s_%s_%s' % (app_label, model_name, self.prev, param,)
        return '%s_%s_%s' % (app_label, model_name, param,)

    @property
    def get_list_url_name(self):
        """
        获取列表页面URL的name
        :return:
        """
        return self.get_url_name('list')

    @property
    def get_add_url_name(self):
        """
        获取添加页面URL的name
        :return:
        """
        return self.get_url_name('add')

    @property
    def get_change_url_name(self):
        """
        获取修改页面URL的name
        :return:
        """
        return self.get_url_name('change')

    @property
    def get_delete_url_name(self):
        """
        获取删除页面URL的name
        :return:
        """
        return self.get_url_name('delete')

3、StarkSite函数中有部分调用需要加self

效果

在列表中自定义列中数据库字段枚举值用中文展示

1、需要把数据库新增字段编辑下

编辑为

from django.db import models


class Depart(models.Model):
    """
    部门表
    """
    title = models.CharField(verbose_name='部门名称', max_length=32)

    def __str__(self):
        return self.title


class UserInfo(models.Model):
    """
    用户表
    """
    name = models.CharField(verbose_name='姓名', max_length=32)

    gender_choices = (
        (1, '男'),
        (2, '女'),
    )
    gender = models.IntegerField(verbose_name='性别', choices=gender_choices, default=1)

    classes_choice = (
        (11, '全栈1期'),
        (21, '全栈3期'),
    )
    classes = models.IntegerField(verbose_name='班级', choices=classes_choice, default=11)

    age = models.CharField(verbose_name='年龄', max_length=32)
    email = models.CharField(verbose_name='邮箱', max_length=32)
    depart = models.ForeignKey(verbose_name='部门', to='Depart')

    def __str__(self):
        return self.name

2、基类中新增函数

def get_choice_text(title, field):
    """
    对于Stark组件中定义列时,choice如果想要显示中文信息,调用此方法即可。
    :param title: 希望页面显示的表头
    :param field: 字段名称
    :return:
    """

    def inner(self, obj=None, is_header=None):
        if is_header:
            return title
        method = "get_%s_display" % field
        return getattr(obj, method)()

    return inner

3、stark组件中调用方式

class UserInfoHandler(StarkHandler):
    # 定制页面显示的列
    list_display = ['name',
                    get_choice_text('性别', 'gender'),
                    get_choice_text('班级', 'classes'),
                    'age', 'email', 'depart',
                    StarkHandler.display_edit,StarkHandler.display_del]

效果:

基类代码:
v1.py

# -*- encoding: utf-8 -*-
"""
@File    : v1.py
@Time    : 2022/1/16 19:59
@Author  : simon
@Email   : 294168604@qq.com
@Software: PyCharm
"""
from django.conf.urls import url
from django.shortcuts import HttpResponse, render
from django.urls import reverse
from django.utils.safestring import mark_safe
from types import FunctionType



def get_choice_text(title, field):
    """
    对于Stark组件中定义列时,choice如果想要显示中文信息,调用此方法即可。
    :param title: 希望页面显示的表头
    :param field: 字段名称
    :return:
    """

    def inner(self, obj=None, is_header=None):
        if is_header:
            return title
        method = "get_%s_display" % field
        return getattr(obj, method)()

    return inner

class StarkHandler(object):
    list_display = []
    def display_edit(self, obj=None, is_header=None):
        """
        自定义页面显示的列(表头和内容)
        :param obj:
        :param is_header:
        :return:
        """
        if is_header:
            return "编辑"
        name = "%s:%s" % (self.site.namespace, self.get_change_url_name,)
        return mark_safe('<a href="%s">编辑</a>' % reverse(name, args=(obj.pk,)))

    def display_del(self, obj=None, is_header=None):
        if is_header:
            return "删除"
        name = "%s:%s" % (self.site.namespace, self.get_delete_url_name,)
        return mark_safe('<a href="%s">删除</a>' % reverse(name, args=(obj.pk,)))

    def get_list_display(self):
        """
        获取页面上应该显示的列,预留的自定义扩展,例如:以后根据用户的不同显示不同的列
        :return:
        """
        value = []
        value.extend(self.list_display)
        return value

    def __init__(self, site, model_class, prev):
        self.site = site
        self.model_class = model_class
        self.prev = prev

    def changelist_view(self, request):
        """
        列表页面
        :param request:
        :return:
        """

        list_display = self.get_list_display()
        # 1. 处理表格的表头
        header_list = []
        if list_display:
            for key_or_func in list_display:
                if isinstance(key_or_func, FunctionType):
                    verbose_name = key_or_func(self, obj=None, is_header=True)
                else:
                    verbose_name = self.model_class._meta.get_field(key_or_func).verbose_name
                header_list.append(verbose_name)
        else:
            header_list.append(self.model_class._meta.model_name)

        # 2. 处理表的内容
        data_list = self.model_class.objects.all()

        body_list = []
        for row in data_list:
            tr_list = []
            if list_display:
                for key_or_func in list_display:
                    if isinstance(key_or_func, FunctionType):
                        tr_list.append(key_or_func(self, row, is_header=False))
                    else:
                        tr_list.append(getattr(row, key_or_func))  # obj.gender
            else:
                tr_list.append(row)
            body_list.append(tr_list)

        return render(
            request,
            'stark/changelist.html',
            {
                'data_list': data_list,
                'header_list': header_list,
                'body_list': body_list
            }
        )

    def add_view(self, request):
        """
        添加页面
        :param request:
        :return:
        """
        # self.models_class
        return HttpResponse('添加页面')

    def change_view(self, request, pk):
        """
        编辑页面
        :param request:
        :param pk:
        :return:
        """
        # self.models_class
        return HttpResponse('编辑页面')

    def delete_view(self, request, pk):
        """
        删除页面
        :param request:
        :param pk:
        :return:
        """
        # self.models_class
        return HttpResponse('删除页面')

    def get_url_name(self, param):
        app_label, model_name = self.model_class._meta.app_label, self.model_class._meta.model_name
        if self.prev:
            return '%s_%s_%s_%s' % (app_label, model_name, self.prev, param,)
        return '%s_%s_%s' % (app_label, model_name, param,)

    @property
    def get_list_url_name(self):
        """
        获取列表页面URL的name
        :return:
        """
        return self.get_url_name('list')

    @property
    def get_add_url_name(self):
        """
        获取添加页面URL的name
        :return:
        """
        return self.get_url_name('add')

    @property
    def get_change_url_name(self):
        """
        获取修改页面URL的name
        :return:
        """
        return self.get_url_name('change')

    @property
    def get_delete_url_name(self):
        """
        获取删除页面URL的name
        :return:
        """
        return self.get_url_name('delete')


    def get_urls(self):
        app_label, model_name = self.model_class._meta.app_label, self.model_class._meta.model_name
        if self.prev:
            patterns = [
                url(r'^list/$', self.changelist_view, name='%s_%s_%s_list' % (app_label, model_name, self.prev)),
                url(r'^add/$', self.add_view, name='%s_%s_%s_add' % (app_label, model_name, self.prev)),
                url(r'^change/(\d+)/$', self.change_view, name='%s_%s_%s_change' % (app_label, model_name, self.prev)),
                url(r'^delete/(\d+)/$', self.delete_view, name='%s_%s_%s_delete' % (app_label, model_name, self.prev)),
            ]
        else:
            patterns = [
                url(r'^list/$', self.changelist_view, name='%s_%s_list' % (app_label, model_name,)),
                url(r'^add/$', self.add_view, name='%s_%s_add' % (app_label, model_name,)),
                url(r'^change/(\d+)/$', self.change_view, name='%s_%s_change' % (app_label, model_name,)),
                url(r'^delete/(\d+)/$', self.delete_view, name='%s_%s_delete' % (app_label, model_name,)),
            ]
        patterns.extend(self.extra_urls())
        return patterns

    def extra_urls(self):
        return []


class StarkSite(object):
    def __init__(self):
        self._registry = []
        self.app_name = 'stark'
        self.namespace = 'stark'

    def register(self, model_class, handler_class=None, prev=None):
        """

        :param model_class: 是models中的数据库表对应的类。 models.UserInfo
        :param handler_class: 处理请求的视图函数所在的类
        :return:
        """
        """
        self._registry = [
            {'model_class':models.Depart,'handler':DepartHandler(models.Depart)},
            {'model_class':models.UserInfo,'handler':UserInfoHandler(models.UserInfo)}
            {'model_class':models.Host,'handler': HostHandler(models.Host) }
        ]
        """
        if not handler_class:
            handler_class = StarkHandler
        self._registry.append({'model_class': model_class, 'handler': handler_class(self,model_class, prev), 'prev': prev})

    def get_urls(self):
        patterns = []
        for item in self._registry:
            model_class = item['model_class']
            handler = item['handler']
            prev = item['prev']
            app_label, model_name = model_class._meta.app_label, model_class._meta.model_name
            if prev:
                patterns.append(url(r'^%s/%s/%s/' % (app_label, model_name, prev,), (handler.get_urls(), None, None)))
            else:
                patterns.append(url(r'%s/%s/' % (app_label, model_name,), (handler.get_urls(), None, None)))

        return patterns

    @property
    def urls(self):
        return self.get_urls(), self.app_name, self.namespace


site = StarkSite()

posted @ 2022-02-20 11:54  simon_T  阅读(47)  评论(0编辑  收藏  举报