Python Web开发学习

【CRM客户关系管理】08.取出app中model的值,根据li

2018-11-25  本文已影响0人  吾星喵

个人博客,欢迎查看:https://blog.starmeow.cn/

Github地址:https://github.com/xyliurui/DjangoCRM

根据注册models配置生成数据列表

取出app中model的值

models详情视图table_detail

在djadmin应用的views.py新建视图

@login_required
def table_detail(request, app_name, model_name):
    """取出指定model里的数据返回到前端"""
    # 拿到admin_class后,通过它获取model
    admin_class = site.enable_admins[app_name][model_name]
    queryset = admin_class.model.objects.all()
    print(queryset)

    return render(request, 'djadmin/table_detail.html', locals())

创建详情的模板table_detail.html

{% extends 'djadmin/base.html' %}

{% block title %}
    数据表详情 - 后台管理
{% endblock %}

{% block content %}
    <h1 class="page-header">应用 - {{ app_name }}</h1>
    {{ queryset }}
    <table class="table table-striped">
        <thead>
        <tr>
            <th>{{ app_name }}</th>
        </tr>
        </thead>
        <tbody>

        </tbody>
    </table>

{% endblock %}

models详情url

修改djadmin应用下的urls,增加详情路由

from django.urls import path
from djadmin.views import index, user_login, user_logout, table_detail

app_name = 'djadmin'

urlpatterns = [
    path('login/', user_login, name='user_login'),  # djAdmin登录
    path('logout/', user_logout, name='user_logout'),  # djAdmin登出
    path('', index, name='index'),  # djAdmin主页
    path('<str:app_name>/<str:model_name>/', table_detail, name='table_detail'),  # 数据表详情
]

修改index.html增加详情链接

<td><a href="{% url 'djadmin:table_detail' app_name=app_name model_name=model_name %}">{{ model_name }}</a></td>

访问这四个页面的详情链接

image.png
<QuerySet [<CustomerInfo: 测试>]>
[10/Nov/2018 10:49:23] "GET /djadmin/crm/customerinfo/ HTTP/1.1" 200 4592
<QuerySet [<UserProfile: LR>]>
[10/Nov/2018 10:49:26] "GET /djadmin/crm/role/ HTTP/1.1" 200 4587
<QuerySet [<UserProfile: LR>]>
[10/Nov/2018 10:49:28] "GET /djadmin/crm/menu/ HTTP/1.1" 200 4587
<QuerySet [<UserProfile: LR>]>
[10/Nov/2018 10:49:31] "GET /djadmin/crm/userprofile/ HTTP/1.1" 200 4587

判断注册类实例化

最终打印出来的queryset = admin_class.model.objects.all()有三个是相同的,也就是没注册三个model里面得到值是一样

原因分析:因为没注册的三个mdoel都共享同一个BaseDjAdmin内存对象(三个model内存地址一样),我们只需要实例化就可以了(实例化后就都有单独的内存空间了)

修改djadmin/sites.py文件,增加判断实例化对象

from djadmin.djadmin_base import BaseDjAdmin


class AdminSite(object):
    def __init__(self):
        self.enable_admins = {}

    # 两个参数,一个表名,一个自定义的admin类
    def register(self, model_class, admin_class=None):
        """注册admin表"""

        # print('register',model_class,admin_class)
        # 获取app名字
        app_name = model_class._meta.app_label
        # 获取表名
        model_name = model_class._meta.model_name
        # 获取表别名
        # model_verbose_name = model_class._meta.verbose_name
        # print(model_verbose_name)

        if admin_class:
            # 如果写了注册的类,就实例化自己
            admin_class = admin_class()
        else:
            # 如果没有写注册的类,就用BaseDjAdmin实例化,防止使用相同的内存地址
            admin_class = BaseDjAdmin()

        # 把model_class赋值给了admin_class,然后在视图中可以通过admin_class找到对应的model类(表名字)
        admin_class.model = model_class

        if app_name not in self.enable_admins:
            self.enable_admins[app_name] = {}
        self.enable_admins[app_name][model_name] = admin_class


# 实例化,就可以调用register方法
site = AdminSite()

然后访问各个链接,都是返回各自的查询集了

[10/Nov/2018 11:11:22] "GET /djadmin/ HTTP/1.1" 200 5415
<QuerySet [<CustomerInfo: 测试>]>
[10/Nov/2018 11:11:24] "GET /djadmin/crm/customerinfo/ HTTP/1.1" 200 4592
<QuerySet [<Role: 销售>, <Role: admin>]>
[10/Nov/2018 11:11:27] "GET /djadmin/crm/role/ HTTP/1.1" 200 4605
<QuerySet [<Menu: 客户库>, <Menu: 主页(绝对)>, <Menu: 主页(动态)>]>
[10/Nov/2018 11:11:31] "GET /djadmin/crm/menu/ HTTP/1.1" 200 4655
<QuerySet [<UserProfile: LR>]>
[10/Nov/2018 11:11:35] "GET /djadmin/crm/userprofile/ HTTP/1.1" 200 4587

根据list_display配置生成数据列表

通过自定义的admin_class类,循环出list_display所有的列

在crm应用下djadmin.py配置中list_display = ['name', 'contact_type', 'contact', 'consultant', 'consult_content', 'status', 'created_time']

显示表头

修改table_detail.html遍历出上方的列表

{% extends 'djadmin/base.html' %}

{% block title %}
    数据表详情 - 后台管理
{% endblock %}

{% block content %}
    <h1 class="page-header">应用 - {{ app_name }}</h1>
    {{ queryset }}
    <table class="table table-striped">
        <thead>
        <tr>
            {% for display_field in admin_class.list_display %}
                <th>{{ display_field }}</th>
            {% endfor %}
        </tr>
        </thead>
        <tbody>

        </tbody>
    </table>
{% endblock %}
image.png

下面通过自定义模板标签显示表头的别名,也就是模型中定义的verbose_name

自定义模板标签

djadmin应用下新建python Package,取名为templatetags,然后再这个包内创建djadmin_tags.py文件

from django.template import Library
from django.utils.safestring import mark_safe


register = Library()


# 显示模型表的中文名称
@register.simple_tag
def build_table_head_name(admin_class):
    th = ''
    for display_field in admin_class.list_display:
        # 获取列中的字段对象
        display_field_obj = admin_class.model._meta.get_field(display_field)
        # print(display_field_obj.verbose_name)
        tmp = "<th>{}</th>".format(display_field_obj.verbose_name)
        th += tmp
    return mark_safe(th)


# 显示表数据
@register.simple_tag
def build_table_body(obj, admin_class):
    """
    生成一条记录的html元素
    :param obj: 一个模型查询集中的一个对象
    :param admin_class: 自定义注册的类
    :return: 得到这个对象要求显示的所有列
    """
    td = ''
    for display_field_name in admin_class.list_display:
        # 根据属性名,获取对象的属性值,两个参数,一个对象obj,一个列名
        display_field_data = getattr(obj, display_field)  # 获取一个对象的属性值,例如<CustomerInfo: 小东>对象,得到他的name属性,值为小东
        tmp = "<td>{}</td>".format(display_field_data)
        td += tmp
    return mark_safe(td)

数据列表中使用模板标签

{% extends 'djadmin/base.html' %}

{% load djadmin_tags %}

{% block title %}
    数据表详情 - 后台管理
{% endblock %}

{% block content %}
    <h1 class="page-header">应用 - {{ app_name }}</h1>
    {{ queryset }}
    <table class="table table-striped">
        <thead>
        <tr>
            <!--
            {% for display_field in admin_class.list_display %}
                <th>{{ display_field }}</th>
            {% endfor %}
            -->
            {% build_table_head_name admin_class %}
        </tr>
        </thead>
        <tbody>
            {% for obj in queryset %}
                <tr>
                    {% build_table_body obj admin_class %}
                </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

现在访问 http://127.0.0.1:8000/djadmin/crm/customerinfo/ 就可以看到相关的数据

image.png

但是其中的选择项的列是数字,比如status显示的1,2,想要显示未报名已报名

修改模板标签选择项显示方式

因为有的字段有choices,有的字段没有choices,需要添加一个判断

继续修改模板标签build_table_body(obj, admin_class)函数

# 显示表数据
@register.simple_tag
def build_table_body(obj, admin_class):
    """
    生成一条记录的html元素
    :param obj: 一个模型查询集中的一个对象
    :param admin_class: 自定义注册的类
    :return: 得到这个对象要求显示的所有列
    """
    td = ''
    for display_field in admin_class.list_display:
        # 获取列中的字段对象
        display_field_obj = admin_class.model._meta.get_field(display_field)
        # print(display_field_obj)
        # 字段对象choices方法,如果有choices,则使用get_xxx_display
        if display_field_obj.choices:
            print('get_{}_display'.format(display_field))
            display_field_data = getattr(obj, 'get_{}_display'.format(display_field))()  # 使用get_xxx_display()需要带括号,调用函数执行结果,而不带括号得到的是函数对象
        else:
            # 根据属性名,获取对象的属性值,两个参数,一个对象obj,一个列名
            display_field_data = getattr(obj, display_field)  # 获取一个对象的属性值,例如<CustomerInfo: 小东>对象,得到他的name属性,值为小东
        tmp = "<td>{}</td>".format(display_field_data)
        td += tmp
    return mark_safe(td)

现在刷新 http://127.0.0.1:8000/djadmin/crm/customerinfo/ 页面

image.png

所有选择项就变成可识别的内容了。

上一篇下一篇

猜你喜欢

热点阅读