一、stark组件

@(Django)[一、stark组件]
stark组件

Stark组件简介

startk组件也可以说是仿照django自带的一个功能,因为有时候django的功能不能满足我们的需求。所以我们新建一个应用叫做stark,在新建一个目录存放我们的代码。

stark
	|____service
		|____stark.py
		
from django.conf.urls import url
from django.shortcuts import HttpResponse,render
from django.utils.safestring import mark_safe
from django.urls import reverse
class ModelStark(object):  # 与某张表关联的样式类
    list_display=["__str__"]
    list_display_links=[]
    def __init__(self,model):
        self.model=model
        self.model_name = self.model._meta.model_name
        self.app_label = self.model._meta.app_label
    def get_edit_url(self,obj):
        name = "%s_%s_change" % (self.app_label, self.model_name)
        edit_url = reverse(name, args=(obj.pk,))
        return edit_url
    def edit(self, obj=None, is_header=False):

        if is_header:
            return "操作"

        return mark_safe("<a href='%s'>编辑</a>" %self.get_edit_url(obj))
    def delete(self, obj=None, is_header=False):
        if is_header:
            return "操作"
        name = "%s_%s_delete" % (self.app_label, self.model_name)
        delete_url = reverse(name, args=(obj.pk,))
        return mark_safe("<a href='%s'>删除</a>" % delete_url)
    def checkbox(self, obj=None, is_header=False):
        if is_header:
            return mark_safe("<input type='checkbox'>")
        return mark_safe("<input type='checkbox'>")
    def add_view(self,request):

        return HttpResponse("add")
    def delete_view(self,request,id):
        print("OOOOOO")
        return HttpResponse("delete")
    def change_view(self,request,id):
        return HttpResponse("change")
    def get_list_display(self):
        newt_list_display=[]
        newt_list_display.extend(self.list_display)
        if not self.list_display_links:
              newt_list_display.append(ModelStark.edit)
        newt_list_display.append(ModelStark.delete)
        newt_list_display.insert(0,ModelStark.checkbox)
        return newt_list_display
    def changelist_view(self,request):
        # 获取标题 [""]
        header_list=[]
        for field in self.get_list_display():
            if callable(field):
                #val=field.__name__.upper()
                val=field(self,is_header=True)
            else:
                if field=="__str__":
                     val=self.model._meta.model_name.upper()
                else:
                     val=self.model._meta.get_field(field).verbose_name



            header_list.append(val)

        # 获取表单数据
        data_list=self.model.objects.all()
        print("self.list_display",self.list_display) # ["id","title"]

        new_data_list=[]
        for obj in data_list:
            temp=[]
            for field in self.get_list_display(): # ["id","title",edit]
                if callable(field):
                    val=field(self,obj)
                else:
                    val=getattr(obj,field)
                    if field in self.list_display_links:  # ["title"]
                        val = mark_safe("<a href='%s'>%s</a>" %(self.get_edit_url(obj),val))
                temp.append(val)
            new_data_list.append(temp)

        print(new_data_list)



        '''
        data_list:
        
        [
         obj1,
         obj2,
        ]
         
            
        new_data_list:       self.list_display: ["id","title",edit]
        
        [
          [1,"python","<a href=''>编辑</a>"],
          [2,"java","<a href=''>编辑</a>"]
        ]
        
        
        
        '''


        return render(request,"stark/changelist.html",locals())
    def get_urls(self):
        app_model=(self.app_label,self.model_name)
        temp=[
            url(r'^add/$', self.add_view,name="%s_%s_add"%app_model),
            url(r'^(\d+)/delete/$', self.delete_view,name="%s_%s_delete"%app_model),
            url(r'^(\d+)/change/$', self.change_view,name="%s_%s_change"%app_model),
            url(r'^$', self.changelist_view,name="%s_%s_list"%app_model),
        ]
        return temp
    @property
    def urls(self):
        return self.get_urls(),None,None
class StarkSite(object):
    def __init__(self):
        self._registry={}

    def register(self,model,modle_stark=None):
        if not modle_stark:
            modle_stark=ModelStark

        self._registry[model]=modle_stark(model)

    def test(self,request):
        return HttpResponse("test")

    def get_urls(self):
        temp=[]

        for model,stark_model_obj in self._registry.items():
            print(model)
            # /app02/book/
            model_name=model._meta.model_name
            app_label=model._meta.app_label
            u=url("%s/%s/"%(app_label,model_name),stark_model_obj.urls)
            temp.append(u)

            ''' 
           
            url("app01/userinfo/,stark_model(userinfo).urls),
            url("app01/blog/,stark_model(blog).urls),
            url("app02/book/,stark_model(book).urls),
        
            '''
        return temp
    @property
    def urls(self):
        return self.get_urls(),None,None
site=StarkSite()

在stark应用下的apps.py加上一句话,django会自动查找项目下的stark文件。

stark
	|____apps.py
from django.apps import AppConfig

from django.utils.module_loading import autodiscover_modules
class StarkConfig(AppConfig):
    name = 'stark'

    def ready(self):
        autodiscover_modules('stark')

为什么它会自动查找所有应用下的apps.py这个文件,在settings.py文件中是这样定义的。"app01.apps.App01Config",这里就是让django启动时候查找应用下的apps.py文件。

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "app01.apps.App01Config"
]

新建一个项目,创建一个叫stark.py的文件

app01
	|___stark.py
from stark.service.stark import site,ModelStark
from .models import *
from django.utils.safestring import mark_safe
from django.urls import reverse
class BookConfig(ModelStark):
    list_display = ["title"]
    list_display_links=["title"]
site.register(Book,BookConfig)

print("app02:  ",site._registry) #

说明:
 首先能确定这是一个单例模式。
首先我们来看一下,在app01项目下都做了什么。

class BookConfig(ModelStark):
    list_display = ["title"]
    list_display_links=["title"]

site.register(Book,BookConfig)

 我们注册了一个Book的表[site.register(Book,BookConfig)],BookConfig是我们传入要访问的方式,这里模仿django的admin。下面我们看一下,传参之后具体做了什么。
 在startk->service->stark.py我们定义了什么。
我们先实例化一个类,site。StarkSite被实例化。注意我们已经传入了一个Book,在register。继续看register。

    def __init__(self):
        self._registry={}
    def register(self,model,modle_stark=None):
        if not modle_stark:
            modle_stark=ModelStark
        self._registry[model]=modle_stark(model)

 我们传入的Book表,和我们仿照django的admin定制的显示的样式。先判断modle_stark是否传入参数,这里我们按默认为空区走。我们看到的是将我们传入的Book表作为字典的key,而它的值就是ModelStark并且传入了Book表。我么在看ModelStark都做了什么。这里我们说明一下,这里的model_stark=None,为空,我们用的是默认的ModelStark这个类。
我们来看一下urls.py

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

from django.shortcuts import HttpResponse

from stark.service.stark import site,ModelStark

from app02 import views

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

 他这里是调用的是site.urls,这个方法。我们看一下stark.py下的site实例化类中的ruls方法。

    @property
    def urls(self):
        return self.get_urls(),None,None
# @property装饰器让调用的时候不在加()简单理解。

 self.get_urls(),None,None这里是要给路由分发。
示例:

url(r"^test/",[(
		url(r"^test/",add),
		url(r"^test/",delete),
		url(r"^test/",change),
	),None,None])

 这里在元组后边写两个None。
跳转到get_urls():

    def get_urls(self):
        temp=[]

        for model,stark_model_obj in self._registry.items():
            print(model)
            # /app02/book/
            model_name=model._meta.model_name
            app_label=model._meta.app_label
            u=url("%s/%s/"%(app_label,model_name),stark_model_obj.urls)
            temp.append(u)

            ''' 
           
            url("app01/userinfo/,stark_model(userinfo).urls),
            url("app01/blog/,stark_model(blog).urls),
            url("app02/book/,stark_model(book).urls),
        
            '''
        return temp

 我们将我们原来添加的那个Book字典拿出来,通过循环提取数据。
注意的是这里,取出项目名,和表明。

            model_name=model._meta.model_name
            app_label=model._meta.app_label

重点:stark_model_obj.urls这里做了什么。
我们得到的是这个url("app02/book/,stark_model(book).urls),这里是通过这个表调用urls。

class StarkSite
	……
    @property
    def urls(self):
        return self.get_urls(),None,None

我们在看一下StarkSite中的get_urls()方法做了什么。

    def get_urls(self):
        app_model=(self.app_label,self.model_name)
        temp=[
            url(r'^add/$', self.add_view,name="%s_%s_add"%app_model),
            url(r'^(\d+)/delete/$', self.delete_view,name="%s_%s_delete"%app_model),
            url(r'^(\d+)/change/$', self.change_view,name="%s_%s_change"%app_model),
            url(r'^$', self.changelist_view,name="%s_%s_list"%app_model),
        ]
        return temp

下面就根据分发的urls进行相应的操作。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bs/css/bootstrap.css/">
</head>
<body>

<h3>数据展示页面</h3>

<div class="container">

    <div class="row">
        <div class="col-md-8 col-md-offset-1">
            <table class="table table-bordered table-striped table-hover">
                <thead>
                      {% for item in header_list %}
                       <td>{{ item }}</td>
                      {% endfor %}

                </thead>
                <tbody>
                      {% for data in new_data_list %}
                          <tr>
                             {% for item in data %}
                             <td>{{ item }}</td>
                             {% endfor %}

                          </tr>
                      {% endfor %}

                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>
posted @ 2018-03-26 11:41  zz小公子  阅读(195)  评论(0)    收藏  举报