django-admin 自定义框架

 

当django一启动的时候,django自带一些URL,并可以访问,有相应的页面。如:admin/ url是django自带,以及admin里面所有的操作 login logout 以及编辑操作的URL。

 

自定义django框架步骤:------数据查看-------

当django程序启动时首先会每个app下的apps.py--下的 ready()  方法,

默认的apps.py

from django.apps import AppConfig


class App0Config(AppConfig):
    name = 'app0'

 

修改apps.py, 让ready()自动去找 自己定义的custom 而不是自带的admin.py文件 。 ###如果admin.py文件也可以 ,只要是自定制的

from django.apps import AppConfig


class App01Config(AppConfig):
    name = 'app01'
    def ready(self):
        """
        当程序运行时,django会找每个APP的apps.py的ready 方法
        :return:
        """
        super(App01Config,self).ready()
        from django.utils.module_loading import autodiscover_modules
        autodiscover_modules('custom')

自定制admin.py  ---->custom.py

print('custom app01')
 
from app03.service import v1  #实现注册方法的是v1 
from app01 import models

v1.site.register(models.App02Userinfo)#
print('cusmtom app02')


from app03.service import v1
from app02 import models
from django.utils.safestring import mark_safe
class display_oprate(v1.BaseCustom):
    def func(self, obj=None,is_header=False):
        if is_header:
            return '操作'
        else:
            """
            显示操作字段
            """
            from django.urls import reverse
            name = "{namespace}:{appname}_{modelname}_change".format(namespace=self.site.namespace,
                                                                     appname=self.model_class._meta.app_label,
                                                                     modelname=self.model_class._meta.model_name)
            url = reverse(name, args=(obj.pk,))  # reverse{namespace:}
            return mark_safe("<a href='{0}'>编辑</a>".format(url))

    def checkbox(self, obj=None,is_header=False):
        if is_header:
            return mark_safe("<input type='checkbox'/>")
        else:
            tag = '<input type="checkbox" value="{0}" />'.format(obj.pk)
            return mark_safe(tag)

    list_display = [checkbox, 'id', 'username','email', func]

class Display_userinfo(v1.BaseCustom):
    list_display=['id','username','email']

class Display_Role(v1.BaseCustom):
    def func(self, obj):
        """
        显示操作字段
        """
        from django.urls import reverse
        name = "{namespace}:{appname}_{modelname}_change".format(namespace=self.site.namespace,
                                                                 appname=self.model_class._meta.app_label,
                                                                 modelname=self.model_class._meta.model_name)
        url = reverse(name, args=(obj.pk,))  # reverse{namespace:}
        return mark_safe("<a href='{0}'>编辑</a>".format(url))

    def checkbox(self, obj):
        tag = '<input type="checkbox" value="{0}" />'.format(obj.pk)
        return mark_safe(tag)

    list_display = [checkbox, 'id', 'title', func] ,这里就是页面上要显示的字符

class Display_test1(v1.BaseCustom):
    def func(self,obj):
        """
        显示操作字段
        """
        from django.urls import reverse
        name="{namespace}:{appname}_{modelname}_change".format(namespace=self.site.namespace,appname=self.model_class._meta.app_label,modelname=self.model_class._meta.model_name)
        url=reverse(name,args=(obj.pk,))# reverse{namespace:}
        return mark_safe("<a href='{0}'>编辑</a>".format(url))
    def checkbox(self,obj):
        tag='<input type="checkbox" value="{0}" />'.format(obj.pk)
        return mark_safe(tag)
    list_display = [checkbox,'id','title',func]

v1.site.register(models.UserInfo,display_oprate) #在页面上要显示操作“编辑”链接,在注册的时个就传入进去,并在v1.py里接收这个参数如下:
        context={
            'result_list':result_list,
            'list_display':self.list_display,
            'display_change':self
        }
v1.site.register(models.Role,Display_Role) v1.site.register(models.test1,Display_test1)

 

目录结构:

 

自定制的admin  v1 文件存储在app03里面。

 

from django.shortcuts import HttpResponse,render,redirect

class BaseCustom(object):
    # list_display = ['id','name']
    list_display = "__all__"
    def __init__(self,model_class,site):

        self.model_class=model_class
        self.site=site
        self.request=None
    @property
    def urls(self):
        from django.conf.urls import url,include
        info=self.model_class._meta.app_label,self.model_class._meta.model_name
        urlpatterns=[
            url(r'^$',self.changelist_view,name='%s_%s_changelist'%info),
            url(r'^add/$',self.add_view,name='%s_%s_add'%info),
            url(r'^(.+)/delete/$',self.delete_view,name='%s_%s_delete'%info),
            url(r'^(.+)/change/$',self.change_view,name='%s_%s_change'%info),

        ]
        return urlpatterns
    def changelist_view(self,request):
        """
        查看列表
        :param request:
        :return:
        """
        self.request=request
        result_list=self.model_class.objects.all()
        context={
            'result_list':result_list,
            'list_display':self.list_display,
            'display_change':self
        }

        return render(request,'custum/change_list.html',context)
    def add_view(self,request):
        data='add_view'
        return HttpResponse(data)
    def delete_view(self,reqeust):
        """

        :param reqeust:
        :return:
        """
        info=self.model_class._meta.app_label,self.model_class._meta.model_name
        data="%s_%s_del"%info
        return HttpResponse(data)
    def change_view(self,request):
        info = self.model_class._meta.app_label, self.model_class._meta.model_name
        data="%s_%s_change_view"%info
        return HttpResponse(data)
    
class Custom(object):
    def __init__(self):
        self._registry={}
        self.namespace='custom'
        self.app_name='custom'

    def register(self,model_class,xx=BaseCustom): #注册方法如admin.site.register(models.Role) model_clss类也就是表的名称,
        """_registry
        {
          _registry[model.Role]:obj
        }
        """

        self._registry[model_class]=xx(model_class,self)
        print(self._registry,self,'----')
        """
        app名称models类名:BaseCustom 类封装了 app名称models类名,site对象
        {<class 'app02.models.Role'>: <app03.service.v1.BaseCustom object at 0x106149c18>, 
        <class 'app01.models.App02Userinfo'>: <app03.service.v1.BaseCustom object at 0x1061499b0>}
        {<class 'app02.models.Role'>: <app03.service.v1.BaseCustom object at 0x106149c18>, 
        <class 'app01.models.App02Userinfo'>: <app03.service.v1.BaseCustom object at 0x1061499b0>,
         <class 'app02.models.test1'>: <app03.service.v1.BaseCustom object at 0x106149940>}
         
        """


    def get_urls(self):
        from django.conf.urls import url,include
        ret=[
            # url(r'login/',self.login,name='login'),
            # url(r'logout/',self.logout,name='logout'),

        ]

        for model_cls,admin_obj in self._registry.items():
            print(model_cls,model_cls._meta.app_label,'---',model_cls._meta.model_name)
                            #app名字                          #模块名字
            app_labe=model_cls._meta.app_label
            model_name=model_cls._meta.model_name
            ret.append(url(r'%s/%s/'%(app_labe,model_name), include(admin_obj.urls))) #反生成,当每个APP的URL进来时,每个APP都 有
            #自己的增删改查。

        return ret

    def login(self,request):
        return HttpResponse('login')
    def logout(self,request):
        return HttpResponse('logout')

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


site=Custom() #site对象

前端展示:

change_list.html :

{% load custom_list %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据列表</title>
</head>
<body>


<h3>数据</h3>
<h3>{% func result_list list_display display_change %} </h3>


</body>
</html>

扩展模板:

from django.template import Library
from types import FunctionType
register=Library()

def inner(result_list,list_display,display_change):
    for row in result_list:
        # yield [getattr(row,name) for name in list_display]
        yield [name(display_change,obj=row) if isinstance(name,FunctionType) else getattr(row,name) for name in list_display]


def table_head(list_display,display_change):
    head_list = []
    for item in list_display:
        if isinstance(item, FunctionType):
            # head_list.append(item.__name__.title())
            yield item(display_change, is_header=True)
        else:
            yield display_change.model_class._meta.get_field(item).verbose_name
            # item 类型  "username"  "email" "id"


@register.inclusion_tag('custum/md.html')#表示要导入一个HTML模板,下面的返回值表示给这个模板使用
def func(result_list,list_display,display_change):

    v=inner(result_list,list_display,display_change)
    
    
    h=table_head(list_display,display_change)
    
    return {'name':v,'name2':h}

 自定制框架--admin---- 增加

custom-list.py

from django.template import Library
from types import FunctionType
register=Library()

def inner(result_list,list_display,display_change):
    print(result_list,'===') #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
    for i in result_list:
        print([str(i)],'------')

    for row in result_list:
        if list_display=='__all__':
            yield [str(row),] #['UserInfo object']
        else:
        # yield [getattr(row,name) for name in list_display]
            yield [name(display_change,obj=row) if isinstance(name,FunctionType) else getattr(row,name) for name in list_display]


def table_head(list_display,display_change):

    for item in list_display:
        if isinstance(item, FunctionType):
            # head_list.append(item.__name__.title())
            yield item(display_change, is_header=True)
        else:
            yield display_change.model_class._meta.get_field(item).verbose_name
            # item 类型  "username"  "email" "id"


@register.inclusion_tag('custum/md.html')#表示要导入一个HTML模板,下面的返回值表示给这个模板使用
def func(result_list,list_display,display_change):

    v=inner(result_list,list_display,display_change)
    
    
    h=table_head(list_display,display_change)

    return {'name':v,'name2':h}

v1.py

def changelist_view(self,request):
        """
        查看列表
        :param request:
        :return:
        """



        #生成页面上的添加按钮:
        #需要的元素: namespace:app_label ,model_name  reverse
        #self.site.namespace
        #self.model_class._meta.app_label

        from django.http.request import QueryDict
        print(request.GET.urlencode())


        param_dict=QueryDict(mutable=True)
        if request.GET:
            param_dict['_changelistfilter']=request.GET.urlencode()

        print(param_dict.urlencode())


        base_add_url=reverse("{2}:{0}_{1}_add".format(self.app_label,self.model_name,self.site.namespace))

        add_url="{0}?{1}".format(base_add_url,param_dict.urlencode())


        self.request=request
        result_list=self.model_class.objects.all()
        context={
            'result_list':result_list,
            'list_display':self.list_display,
            'display_change':self,
            'add_url':add_url
        }

        return render(request,'custum/change_list.html',context)

添加操作:

   def add_view(self,request):
        """
        添加数据
        :param request:
        :return:
        """


        print(request.GET('_changelistfilter'))
        if request.method=='GET':
            model_form_obj=self.get_add_or_edit_model_form()()
        else:
            model_form_obj=self.get_add_or_edit_model_form()(data=request.POST,files=request.FILES)
            if model_form_obj.is_valid():
                model_form_obj.save()
                #添加成功,跳转页面
                #/custom/app01/userinfo/+request.GET.get('_changelistfileter')
                base_list_url = reverse("{2}:{0}_{1}_changelist".format(self.app_label, self.model_name, self.site.namespace))

                list_url = "{0}?{1}".format(base_list_url, request.GET('_changelistfilter'))
                return redirect(list_url)

        from django.forms import ModelForm

        model_form_cls=self.get_add_or_edit_model_form()

        context={
            'form':model_form_cls,
        }
        data='add_view'

        return render(request,'custum/add.html',context)

add.html

<h3>添加数据</h3>
<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="提交">
</form>

 

修改功能:

   def change_view(self,request,pk):

        obj=self.model_class.objects.filter(pk=pk).first()
        if not obj:
            return HttpResponse('id不存在 ')

        if request.mthod=='GET':
            model_form_obj = self.get_add_or_edit_model_form()(instance=obj)
        else:
            model_form_obj=self.get_add_or_edit_model_form()(data=request.POST,instance=obj)
            
        context={
            'form':model_form_obj
        }
        return render(request,'custum/edit.html',context)
    

 

posted @ 2017-09-08 10:04  tonycloud  阅读(485)  评论(0编辑  收藏  举报