stark组件02

1、怎么在显示页面添加新字段(a标签)?在admin.py下注册就好了

当我们需要在admin页面添加新的a标签时,需要引入一个类似safe功能的模块

from django.utils.safestring import mark_safe

from django.contrib import admin
# Register your models here.
from .models import *
from django.utils.safestring import mark_safe

class BookConfig(admin.ModelAdmin):
    def edit(self):
            return mark_safe("<a href='/stark/app01/book/3/change/'>编辑</a>")

    def delete(self):
            return mark_safe("<a href='/stark/app01/book/3/change/'>编辑</a>")
    list_display = ["id","title",edit,delete]
admin.site.register(Book,BookConfig)

2、关于url的反向解析

(1)直接添加name字段

问题:会导致名字重复

优化:

想要的格式:

    def get_urls(self):
        temp=[]
        model_name=self.model._meta.model_name  # 用户当前表名
        app_label=self.model._meta.app_label    # 当前的项目名称
        app_model=(app_label,model_name)

        temp.append(url("^$",self.show_list_view,name="%s_%s_showlist"%app_model))
        temp.append(url("^add/$",self.add_view,name="%s_%s_add"))
        temp.append(url("^(\d+)/change/$",self.change_view,name="%s_%s_change"))
        temp.append(url("^(\d+)/delete/$",self.del_view,name="%s_%s_delete"))

        return temp

 

3、视图处理

问题:如何显示数据

也不能直接写data.title  原因:假如title只是当前表的字段,而当用户访问的是别的表,没有该字段,写死了!!

 

(1)、先看懂admin是怎做的

 

from django.contrib import admin

# Register your models here.

from .models import *
from django.utils.safestring import mark_safe

class BookConfig(admin.ModelAdmin):
    def edit(self):
            return mark_safe("<a href='/stark/app01/book/3/change/'>编辑</a>")

    def delete(self):
            return mark_safe("<a href='/stark/app01/book/3/change/'>删除</a>")


    list_display = ["id", "title","price",edit,delete]  # z这个list_display只针对Book表

admin.site.register(Book,BookConfig)
admin

 

(2)、

#  自己定制的stark组件

from stark.service.site import site,ModelSatrk

from .models import *
from django.utils.safestring import mark_safe
#
class BookConfig(ModelSatrk):

    # def edit(self):
    #     return mark_safe("<a href='/stark/app01/book/3/change/'>编辑</a>")
    #
    # def delete(self):
    #     return mark_safe("<a href='/stark/app01/book/3/change/'>编辑</a>")

    # list_display = ["id", "title","price"]  # z这个list_display只针对Book表
    pass
# 自制注册功能(admin表的注册
site.register(Book,BookConfig)

理解list_display,当上面用户定义了,就用用户的

class ModelSatrk(object):  # 针对某张表的样式
    list_display=[]  # 提供给用户自己定制显示字段
    def __init__(self,model,site):
        # http://127.0.0.1:8000/stark/app01/book/
        self.model=model  # 获取是当前哪张表对应的样式类对象(用户访问当前类
        self.site=site  # 拿到一个全局的单例对象

    def show_list_view(self,request):
        print("self.model",self.model)  # 打印当前表
        data_list = self.model.objects.all()   # 去数据库取来的所有数据 对象
        print("self.list_display",self.list_display)  # 用户定义了self.list_display ['id', 'title', 'price']
                                                    # 用户没有定义self.list_display[]
        return render(request,"stark/show_list.html",locals())

分2中情况,

 #  我们想要构建的数据格式
   # '''
    #     [
    #             [1,"xxx"],
    #             [2,"xxxxx"],
    #             [3,"xxxxxxx'],
    #       ]
    #     '''

1\当用户定义了list_display,

class ModelSatrk(object):  # 针对某张表的样式
    list_display=[]  # 提供给用户自己定制显示字段
    def __init__(self,model,site):
        # http://127.0.0.1:8000/stark/app01/book/
        self.model=model  # 获取是当前哪张表对应的样式类对象(用户访问当前类
        self.site=site  # 拿到一个全局的单例对象

    def show_list_view(self,request):
        print("self.model",self.model)  # 打印当前表
        data_list = self.model.objects.all()   # 去数据库取来的所有数据 对象
        print("self.list_display",self.list_display)  # 用户定义了self.list_display ['id', 'title', 'price']
                                                    # 用户没有定义self.list_display[]
        # 做成下面我们想要的数据格式
        new_data_list=[]  # 定义一个新的空列表来存放最后的数据
        for obj in data_list:
            temp=[]
            # 当用户定义了list_display的情况  利用反射求值
            for field_str in self.list_display: # ['id', 'title', 'price'] 取出来的field_str:字段的字符串
                val=getattr(obj,field_str)  # 需要用到反射来取值
                temp.append(val)
            new_data_list.append(temp)
        print(new_data_list)   # [[1, '《看见》---柴静', Decimal('12.00')], 
                    [2, '《围城》---钱钟书', Decimal('12.00')]]
return render(request,"stark/show_list.html",locals())
<div class="container">
    <div class="row">
        <table class="table table-stripped table-hover">
{#        标题 #}
            <thead>
            
            </thead>
            <tbody>
{#          data是每本书的对象  #}
            {% for data in new_data_list %}
                <tr>
                    {% for item in data %}
                        <td>{{ item }}</td>
                    {% endfor %}
                </tr>
            {% endfor %}

            
            </tbody>
        </table>
    </div>
</div>
HTML

知识点:

反射getattr

class Person(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age

alex=Person("alex",33)

# print(alex.name)   # alex
# print(alex.age)     # 33

# 当给你的是alex对象,s=“name”字符串,求name
v=getattr(alex,"name")
print(v)   # alex


v=getattr(alex,"age、")
print(v)   # 33

结果:

 val = getattr(obj,field)

4、添加新的显示字段

问题:当用户定制的list_display,为['id', 'title', 'price',delete,edit] ,还有字符串和函数名,如何展示页面

方法一:判断是不是为字符串

缺陷:不能判断是否属于当前属于obj的字段

方法二:用callable判断是否为可调用的变量(可执行)

def foo():
    print("foo")

print(callable(foo))  # True

 site.py 模板文件

class ModelSatrk(object):  # 针对某张表的样式
    list_display=[]  # 提供给用户自己定制显示字段
    def __init__(self,model,site):
        # http://127.0.0.1:8000/stark/app01/book/
        self.model=model  # 获取是当前哪张表对应的样式类对象(用户访问当前类
        self.site=site  # 拿到一个全局的单例对象

    def show_list_view(self,request):
        print("self.model",self.model)  # 打印当前表
        data_list = self.model.objects.all()   # 去数据库取来的所有数据 对象
        print("self.list_display",self.list_display)  # 用户定义了self.list_display ['id', 'title', 'price']
                                                    # 用户没有定义self.list_display[]
        # 做成下面我们想要的数据格式
        new_data_list=[]
        for obj in data_list:   #  obj:当前每本书的对象
            temp=[]
            # 当用户定义了list_display的情况  利用反射求值
            for field in self.list_display: # ['id', 'title', 'price',delete,edit] ,
                if callable(field): #  当遇到delete,edit函数
                    val=field(self,obj)     # 执行函数返回的返回值
                else:       # 'id', 'title', 'price'
                    val=getattr(obj,field)   # 利用反射getattr取值
                temp.append(val)
            new_data_list.append(temp)
        print(new_data_list)   # [[1, '《看见》---柴静', Decimal('12.00')], [2, '《围城》---钱钟书', Decimal('12.00')]]

    # 添加新的标签:
        # [
        #   [1, '《看见》---柴静', Decimal('12.00'), "<a href='/stark/app01/book/3/change/'>编辑</a>", "<a href='/stark/app01/book/3/delete/'>删除</a>"],
        #  [2, '《围城》---钱钟书', Decimal('12.00'), "<a href='/stark/app01/book/3/change/'>编辑</a>", "<a href='/stark/app01/book/3/delete/'>删除</a>"]
        return render(request,"stark/show_list.html",locals())

 

 执行edit函数时,先从自己类下找

问题:

 

这里的先将url写死,需要将url反向解析出来

 ----------------------------------------------------------------------

 

5、生成表头信息

知识点:verbose_name --->显示描述信息

    def show_list_view(self,request):
        print("self.model",self.model)  # 打印当前表
        # 生成表表头
        header_list=[]
        for field in self.list_display: # ["id","title","price","edit"]
            if callable(field):
                # header_list.append(field.__name__)
                val = field(self,is_header=True)  # 定义了一个is_header=True变量
                header_list.append(val)
            else:
                field_obj=self.model._meta.get_field(field)
                header_list.append(field_obj.verbose_name)  # verbose_name 显示

 

想要自定义表头信息

关键点:定义一个变量is_header来判断

 

from stark.service.site import site,ModelSatrk

from .models import *
from django.utils.safestring import mark_safe
#
class BookConfig(ModelSatrk):

    def edit(self,obj=None,is_header=False):
        if is_header:
            return "操作"
        return mark_safe("<a href='/stark/app01/book/%s/change/'>编辑</a>"%obj.pk)

    def delete(self,obj=None,is_header=False):
        if is_header:
            return "操作"
        # 如何反向解析url
        return mark_safe("<a href='/stark/app01/book/%s/delete/'>删除</a>"%obj.pk)

    list_display = ["id","title","price",edit,delete]  # z这个list_display只针对Book表
# 自制注册功能(admin表的注册
site.register(Book,BookConfig)

 

 

False 当第一次取数据(取表单数据)是false ---》取数据部分
    第二次取数据是将改为True -----> 取标头部分

 

 

 

 

posted @ 2018-03-13 20:34  小杜要加油  阅读(208)  评论(0)    收藏  举报