基于Django-admin实现stark组件

一、url的分发练习

from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import  HttpResponse
def index(request):
    return HttpResponse("首页")
    
    
def add(request):                         #add视图函数
    return HttpResponse("add")
def list_view(request):                  #list_view视图函数
    return HttpResponse("list_view")
def change(request,id):                  #change视图函数
    return HttpResponse("change")
def delete(request,id):                  #delete视图函数
    return HttpResponse("delete")
    
    
def get_urls2():                        #url的二级分发函数
    temp=[
        url("^add/$",add),
        url("^$",list_view),
        url("^(\d+)/change/$",change),
        url("^(\d+)/delete/$",delete),
    ]
    return temp
    
def get_urls():
    temp=[]
    for model,model_class_obj in admin.site._registry.items(): # 模型类:该模型类的配置类对象 {Book:ModelAdmin(Book),Publish:ModelAdmn(Publish),....}
          app_name=model._meta.app_label                      #得到应用名
          model_name=model._meta.model_name
          temp.append(url(r"%s/%s/"%(app_name,model_name),(get_urls2(),None,None)))   #url做分发,后面跟元组,元组第一项为一个列表
    return  temp
    
from stark.service.sites import site
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r"^stark",(get_urls(),None,None))
]

二、实现stark组件

app01应用的models.py文件:

from django.db import models
class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    age=models.IntegerField()
    def __str__(self):
        return self.name
class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name=models.CharField( max_length=32)
    city=models.CharField( max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name
class Book(models.Model):
    nid = models.AutoField(primary_key=True,verbose_name="编号")
    title = models.CharField( max_length=32,verbose_name="名称")
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2,verbose_name="价格")
    # 与Publish建立一对多的关系,外键字段建立在多的一方
    publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
    authors=models.ManyToManyField(to='Author',)
    def __str__(self):
        return self.title
        
        
#执行下面python语句生成相关表(数据迁移)
# python3 manage.py makemigrations
# python3 manage.py migrate

项目下的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',
    "app02.apps.App02Config",
    "stark.apps.StarkConfig",
]

STATIC_URL = '/static/'
STATICFILES_DIRS=[
    os.path.join(BASE_DIR,"static")
]

项目的urls.py文件:

from django.conf.urls import url
from django.contrib import admin
from stark.service.sites import site
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^stark/', site.urls),               #模拟admin的实现方式,在stark目录后面进行分发
]

app01应用的stark.py文件对app01的应用表进行注册:

from stark.service.sites import site,ModelStark
from app01.models import Book
from app01.models import Publish
from app01.models import Author
class BookConfig(ModelStark):
    # def display_authors(self, obj=None,is_header=False):     #显示多对多字段,单独定义函数实现方式
    #
    #     if is_header:
    #         return "作者"
    #     s=[]
    #     for author in obj.authors.all():
    #         s.append(author.name)
    #
    #     return " ".join(s)
    list_display = ["nid","title","price","publish","authors",]
    # list_display = ["nid","title","price","publish",display_authors]
site.register(Book,BookConfig)
site.register(Publish)
site.register(Author)

项目下的stark目录下apps.py定义执行各个应用的stark.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')      # 执行每一个app下的stark.py

项目下的stark目录下service目录下sites.py定义对用户访问url的分发:

from django.conf.urls import url
from django.shortcuts import HttpResponse, render
from django.utils.safestring import mark_safe
class ModelStark():                    #将增,删,改,查写到ModelStark类中,这样谁调用类中的功能,self.model就是用户访问的表
    list_display = ["__str__", ]
    def __init__(self, model, site):
        self.model = model
        self.site = site
    def edit(self, obj=None, is_header=False):
        if is_header:
            return "操作"                                                   #表头返回 "操作"
        return mark_safe("<a href='%s/change'>编辑</a>" % obj.pk)        #mark_safe会识别返回的html标签
    def delete(self, obj=None, is_header=False):
        if is_header:
            return "操作"
        return mark_safe("<a href='%s/delete'>删除</a>" % obj.pk)
    def checkbox(self, obj=None, is_header=False):
        if is_header:
            return "选择"
        return mark_safe("<input type='checkbox' pk=%s>" % obj.pk)        #在对应位置显示多选框
    def add(self, request):
        return HttpResponse("add")
    def new_list_display(self):                 #新的显示样式,这样所有表的显示都有多选框,编辑和删除操作
        temp = []
        temp.append(ModelStark.checkbox)
        temp.extend(self.list_display)
        temp.append(ModelStark.edit)
        temp.append(ModelStark.delete)
        return temp
    def list_view(self, request):
        print(self.model)
        data_list = self.model.objects.all()
        print("list_display", self.list_display)  # ["nid","title","price",edit]
        # 处理表头
        header_list = []
        for field in self.new_list_display():
            if isinstance(field, str):                              #判断field是字符串类型
                if field == "__str__":                            #字段是__str__
                    val = self.model._meta.model_name.upper()        #表头显示表名的大写字母
                else:
                    field_obj = self.model._meta.get_field(field)
                    val = field_obj.verbose_name                      #得到字段的verbose_name,定义后可以显示中文
            else:
                val = field(self, is_header=True)                  #field是函数,执行函数
            header_list.append(val)
        # 处理表单数据
        new_data_list = []
        for obj in data_list:
            temp = []
            for field in self.new_list_display():  # ["nid","title","price","authors",edit]    ['__str__']     ["title","price"]
                if isinstance(field, str):
                    try:
                        from django.db.models.fields.related import ManyToManyField
                        field_obj = self.model._meta.get_field(field)          #得到field的字段对象
                        if isinstance(field_obj, ManyToManyField):            #判断是多对多关系的字段
                            l = []
                            for i in getattr(obj, field).all():             #.all()得到所有的对象,否则none
                                l.append(str(i))
                            val = ",".join(l)
                        else:
                            val = getattr(obj, field)
                            print("val", val)
                    except Exception as e:
                        val = getattr(obj, field)                      #反射,取到字段名
                else:
                    val = field(self, obj)
                temp.append(val)
            new_data_list.append(temp)
        return render(request, "list_view.html", locals())
    def change(self, request, id):
        return HttpResponse("change")
    def delete_view(self, request, id):
        return HttpResponse("delete_view")
    def get_urls2(self):
        temp = [
            url("^add/$", self.add),
            url("^$", self.list_view),
            url("^(\d+)/change/$", self.change),
            url("^(\d+)/delete/$", self.delete_view),
        ]
        return temp
    @property
    def urls2(self):
        return self.get_urls2(), None, None
        
        
class StarkSite():
    def __init__(self, ):
        self._registry = {}
    # 一级分发
    def get_urls(self):
        temp = []
        for model, model_class_obj in self._registry.items():  # {Book:ModelAdmin(Book),Publish:ModelAdmn(Publish),....}
            app_name = model._meta.app_label
            model_name = model._meta.model_name
            temp.append(url(r"%s/%s/" % (app_name, model_name), model_class_obj.urls2))  #接着二级分发
        return temp
    @property
    def urls(self):
        return self.get_urls(), None, None
    def register(self, model, admin_class=None, **options):
        if not admin_class:
            admin_class = ModelStark
        self._registry[model] = admin_class(model, self)
        
        
site = StarkSite()

list_view.html页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bs/css/bootstrap.css">
</head>
<body>
<h3>查看数据</h3>
<div>
    <div>
        <div>
            <table class="table table-bordered table-hover table-striped">
                <thead>
                     <tr>
                          {% for foo in header_list %}
                          <th>{{ foo }}</th>
                          {% endfor %}
                     </tr>
                </thead>
                <tbody>
                      {% for new_data in new_data_list %}
                      <tr>
                         {% for foo in new_data %}
                         <td>{{ foo }}</td>
                         {% endfor %}
                      </tr>
                      {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>

三、显示多对多字段的另一种方法

stark.py注册表时自定义函数:

class BookConfig(ModelStark):
    def display_authors(self, obj=None,is_header=False):     #显示多对多字段
        if is_header:
            return "作者"
        s=[]
        for author in obj.authors.all():
            s.append(author.name)
        return " ".join(s)
    list_display = ["nid","title","price","publish",display_authors]

sites.py里面的ModelStark类定义的list_view

def list_view(self, request):
    print(self.model)
    data_list = self.model.objects.all()
    print("list_display", self.list_display)  #  ["nid","title","price",edit]
    # 处理表头
    # header_list=["ID","名称","价格"]
    header_list=[]
    for field in self.new_list_display():
        if isinstance(field,str):
            if field=="__str__":
                val=self.model._meta.model_name.upper()
            else:
                field_obj=self.model._meta.get_field(field)
                val=field_obj.verbose_name
        else:
            val=field(self,is_header=True)
        header_list.append(val)
    # 处理表单数据
    new_data_list = []
    for obj in data_list:
        temp = []
        for field in self.new_list_display():  #   ["nid","title","price","authors",edit]    ['__str__']     ["title","price"]
            if isinstance(field,str):
                val = getattr(obj, field)
            else:
                val=field(self,obj)
            temp.append(val)
        new_data_list.append(temp)

页面显示效果图:

原文地址:http://blog.51cto.com/qidian510/2129950

时间: 2024-10-06 07:05:27

基于Django-admin实现stark组件的相关文章

Django——stark组件

stark组件是仿照django的admin模块开发的一套组件,它的作用是在网页上对注册的数据表进行增删改查操作. 一.配置 1.创建stark应用,在settings.py中注册stark应用 stark APP专门用于存放自定义组件的核心代码. manage.py@stark_demo > startapp stark 在settings.py文件注册stark: INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth'

Django admin 组件 原理分析与扩展使用 之 sites.py (一)

一 . 前言 Django 提供了admin 组件 为项目提供基本的管理后台功能(对数据表的增删改查). 本篇文章通过 admin源码 简单分析admin 内部原理 ,扩展使用方式,为以后进行定制和自己开发组件做铺垫. 二. 简单使用 1.在app 目录下的admin.py 中通过注册表 from django.contrib import admin from blog01.models import * admin.site.register([UserInfo,User,Blog]) #

基于Django的Rest Framework框架的认证组件

0|1一.认证组件的作用 在一个程序中有一些功能是需要登录才能使用的,原生Django中的auth组件可以用来解决这个认证问题,drf框架中也有对应的认证组件来解决这个问题. models.py from django.db import models # Create your models here. class User(models.Model): name = models.CharField(max_length=16) pwd = models.CharField(max_leng

基于Django的Rest Framework框架的序列化组件

本文目录 一 Django自带序列化组件 二 rest-framework序列化之Serializer 三 rest-framework序列化之ModelSerializer 四 生成hypermedialink(极少数) 五 序列化组件之请求数据校验和保存功能 序列化组件源码分析 回到目录 一 Django自带序列化组件 详见 回到目录 二 rest-framework序列化之Serializer models部分: from django.db import models # Create

python Stark 组件

Django Admin 是对model中 对应的数据表进行增删改查的组件,对每个APP下面已注册的model表进行增删改查.而stark组件仿照Admin组件开发. Admin的常用配置:  Filedstes 使用方法和效果如下图 Action 使用方法和效果图 需要在My_AppConfig(admin.ModeAdmin)中编写自定义函数 需要注意的:(1)该函数在select下拉框中 作为value值 (2)该函数有两个参数,分别是request.queryset (3)前端的复选框,

crm 使用stark组件

# Create your models here. from django.db import models class Department(models.Model): """ 部门表 市场部 1000 销售 1001 """ title = models.CharField(verbose_name='部门名称', max_length=16) code = models.IntegerField(verbose_name='部门编号',

使用自己的stark组件实现crm系统

因为stark用到了templates里面的html页面文件,所以要整合在一个app里,在stark里面创建名字为templates的Python Package,将之前的html页面拷贝在stark组件里面的templates里面,然后拷贝stark组件 二.实现crm逻辑 CRM即客户关系管理,是指企业用CRM技术来管理与客户之间的关系 1.创建数据库 在app01应用下的models.py文件: from django.db import models class Department(m

stark组件配置,二层URL

1.django的admin配置 2 stark组件开发 3.2层url分发 4.小结 1.django的admin配置 model.py from django.db import models # Create your models here. class UserInfo(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.

stark组件

一 . 需求 仿照Django中的admin , 开发了自己的stark组件,实现类似数据库客户端的功能,对数据进行增删改查 . 二 . 实现思路 1 . 在settings配置里分别注册三个APP  # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions',