• Python Day 75 Django框架 CRM项目(版本一)、


      ##CRM版本一实现功能

    #1、新建一个stark组件
        组件就是应用
       一个项目可以有多个应用
       一个应用可以用在多个项目中 #2、参考admin源码 实现路由分发 #3、数据展示 表头展示 表单展示 #4、自定义数据列 #5、反向解析 #掌握技术点 from app01 import models models.Book._meta.app_label #获得模型表所在的应用名'app01' models.Book._meta.model_name #获得模型表对应的字符串名'book' from app01 import models models.Book._meta.get_field('title') <django.db.models.fields.CharField: title> # 获取字段对象 models.Book._meta.get_field('title').verbose_name '书名' models.Book._meta.get_field('price').verbose_name # 获取字段对象verbose_name属性 当你没有指定的时候默认是字段字符串名'price'

      ##models 模型表结构

    from django.db import models
    
    
    # Create your models here.
    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32)
        age=models.IntegerField()
        # 与AuthorDetail建立一对一的关系
        authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)
    
        def __str__(self):
            return self.name
    
    class AuthorDetail(models.Model):
        nid = models.AutoField(primary_key=True)
        birthday=models.DateField()
        telephone=models.BigIntegerField()
        addr=models.CharField( max_length=64)
    
    
        def __str__(self):
            return self.addr
    
    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)
        title = models.CharField(max_length=32,verbose_name='书名')
        publishDate=models.DateField(verbose_name='出版日期')
        price=models.DecimalField(max_digits=5,decimal_places=2, verbose_name='价格')
        # 与Publish建立一对多的关系,外键字段建立在多的一方
        publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)  # django 2.0版本必须写 1.0默认
        # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
        authors=models.ManyToManyField(to='Author',)
    
        def __str__(self):
            return self.title
    View Code

      ##修改启动文件 C:starkprostarkapps.py

    启动
        django一启动就要执行每一个应用下的stark.py(单独新建的一个文件)文件(django默认会启动admin.py文件)
    
    配置文件中注册
        INSTALLED_APPS = [
            'stark.apps.StarkConfig',
        ]
    在StarkConfig类中 固定写ready方法
        from django.apps import AppConfig
        from django.utils.module_loading import autodiscover_modules
    
        class StarkConfig(AppConfig):
            name = 'stark'
    
            def ready(self):
                # 项目启动就会自动查找每一个应用下的stark.py文件
                return autodiscover_modules('stark')

      ##注册源码

    #模拟Django应用程序下每一个admin.py文件注册功能
    
    #路径:
        C:starkprostarkservicestark.py
    #基础注册模板:
        
        class ModelStark(object):
            def __init__(self,model):
                self.model = model
        class StarkSite(object):
            def __init__(self, name='admin'):
                self._registry = {}  # model_class class -> admin_class instance
    
            def register(self, model, admin_class=None, **options):
                if not admin_class:
                    admin_class = ModelStark
                self._registry[model] = admin_class(model)
            @property
            def urls(self):
                return self.get_urls(), None, None
        site = StarkSite()
    #配置路由urls:注意:自定义生成的site对象点urls,这里的urls不是属性而是一个方法被property修饰的方法
        from django.conf.urls import url
        from django.contrib import admin
        from stark.service.stark import site
        urlpatterns = [
            url(r'^admin/', admin.site.urls),
            url(r'^stark/', site.urls),
        ]

      ##开始实现一级路由分发:C:starkprostarkservicestark.py

    from django.conf.urls import url
    from django.shortcuts import HttpResponse
    class ModelStark(object):
        def __init__(self,model):
            self.model = model
    class StarkSite(object):
        def __init__(self, name='admin'):
            self._registry = {}  # model_class class -> admin_class instance
    
        def register(self, model, admin_class=None, **options):
            if not admin_class:
                admin_class = ModelStark
            self._registry[model] = admin_class(model)
        def test(self,request):
            return HttpResponse('test')
        def get_urls(self):
            #先定义一个列表,因为要给调用者返回列表
            tmp = []
            #循环字典_registry
            for model_class,config_obj in self._registry.items():
                # print(model_class) #<class 'app01.models.Author'> 类字符串
                # print(config_obj) #<stark.service.stark.ModelStark object at 0x000001A79CC58C18> 配置类对象
    
                #获得模型表所在的应用名
                app_label = model_class._meta.app_label
                # 获得模型表对应的字符串名
                model_name = model_class._meta.model_name
                tmp.append(
                    url(r'^%s/%s/'%(app_label,model_name),self.test)
                )
            return tmp
        @property
        def urls(self):
            return self.get_urls(), None, None
    
    site = StarkSite()

      ##stark二级路由设计

    用配置对象解决二级路由。解决的问题是:不同表对应不同的对象,展示到页面上的内容也不一样,一次不能直接使用同一对象site来进行路由二级分发,不然不同路径内容却是一样的
    
    操作文件:C:starkprostarkservicestark.py
    from django.conf.urls import url
    from django.shortcuts import HttpResponse
    class ModelStark(object):
        def __init__(self,model):
            self.model = model #self.model是指拿到当前对象所对应的模型表名,即四张表对应都不一样
        def list_view(self, request):
            #查看self.model  <class 'app01.models.Book'> 那张表查看就代表谁
            print(self.model)
            return HttpResponse('list')
    
        def add_view(self, request):
            return HttpResponse('add')
    
        def edit_view(self, request, id):
            return HttpResponse('edit')
    
        def delete_view(self, request, id):
            return HttpResponse('delete')
        @property
        def urls(self): #此处的self是指配置类对象
            tmp = [
                url(r'^$',self.list_view),
                url(r'^add/',self.add_view),
                url(r'^edit/(d+)/',self.edit_view),
                url(r'^delete/(d+)/',self.delete_view),
            ]
    
            return tmp,None,None
    class StarkSite(object):
        def __init__(self, name='admin'):
            self._registry = {}  # model_class class -> admin_class instance
    
        def register(self, model, admin_class=None, **options):
            if not admin_class:
                admin_class = ModelStark
            self._registry[model] = admin_class(model)
        def test(self,request):
            return HttpResponse('test')
        def get_urls(self):
            #先定义一个列表,因为要给调用者返回列表
            tmp = []
            #循环字典_registry
            for model_class,config_obj in self._registry.items():
                # print(model_class) #<class 'app01.models.Author'> 类字符串
                # print(config_obj) #<stark.service.stark.ModelStark object at 0x000001A79CC58C18> 配置类对象
    
                #获得模型表所在的应用名
                app_label = model_class._meta.app_label
                # 获得模型表对应的字符串名
                model_name = model_class._meta.model_name
                tmp.append(
                    url(r'^%s/%s/'%(app_label,model_name),config_obj.urls)
                )
            return tmp
        @property
        def urls(self):
            return self.get_urls(), None, None
    
    site = StarkSite()

      ##动态展示数据:

    def list_view(self, request):
        #查看self.model  <class 'app01.models.Book'> 那张表查看就代表谁
        # print(self.model)
    
        queryset = self.model.objects.all()
        # 表头展示
        header_list = []
        for field in self.list_display:
            if field == '__str__': #当用户没有指定list_display 默认展示当前表的大写名字
                val = self.model._meta.model_name.upper()
            else:
                val = self.model._meta.get_field(field).verbose_name
            header_list.append(val)
        #表单展示
        body_list = [] #格式定义 [[obj1.title,obj1.price],[obj2.title,obj2.price],[]]
    
        for obj in queryset:
            tmp = []
            for field in self.list_display:#注意这里的list_display查找顺序,先查自己的,在查全局的,然后循环要展示的字段
                val = getattr(obj,field) #通过反射获取obj对象中field字段所对应的值
    
                tmp.append(val)
    
            body_list.append(tmp)
    
    
        return render(request,'stark/list_view.html',locals())
        
    
    #前端:
        <div class="container">
        <div class="row">
            <h2 class="text-center">数据展示</h2>
            <table class="table table-striped table-bordered table-hover">
                <div class="col-md-8 col-md-offset-2">
                    <thead>
                        <tr>
                            {% for foo in header_list %}
                            <td>{{ foo }}</td>
                            {% endfor %}
                        </tr>
                    </thead>
                    <tbody>
                    {% for body in body_list %}
                        <tr>
                            {% for  foo in body %}
                                <td>
                                    {{ foo }}
                                </td>
                            {% endfor %}
                        </tr>
                    {% endfor %}
                    </tbody>
                </div>
            </table>
    </div>
    </div>

      ##自动生成数据:

    1、通过给定函数参数默认值,来对函数附加额外功能
    2、checkbox、编辑、删除 默认所有的表都生成这三个字段
    
    在注册stark文件
    from stark.service.stark import site,ModelStark
    from app01 import models
    from django.utils.safestring import mark_safe
    site.register(models.Author)
    site.register(models.AuthorDetail)
    
    class BookConfig(ModelStark):
    
        list_display = ['title','price','publishDate']
    site.register(models.Book,BookConfig)
    site.register(models.Publish)
    
    C:starkprostarkservicestark.py
    from django.conf.urls import url
    from django.shortcuts import HttpResponse,render,redirect
    from django.utils.safestring import mark_safe
    
    
    class ModelStark(object):
        list_display = ['__str__',]
        def __init__(self,model):
            self.model = model #self.model是指拿到当前对象所对应的模型表名,即四张表对应都不一样
    
        def check_box(self,is_header=False):
            if is_header:
                return '选择'
            return mark_safe('<input type="checkbox"/>')
        def edit_col(self,is_header=False):
            if is_header:
                return '编辑'
            return mark_safe('<a href=''>编辑</a>')
        def delete_col(self,is_header=False):
            if is_header:
                return '删除'
            return mark_safe('<a href=''>删除</a>')
    
        def get_new_list(self):
            tmp=[]
            tmp.append(ModelStark.check_box)
            tmp.extend(self.list_display)
            tmp.append(ModelStark.edit_col)
            tmp.append(ModelStark.delete_col)
            return tmp
        def list_view(self, request):
            #查看self.model  <class 'app01.models.Book'> 那张表查看就代表谁
            # print(self.model)
    
            queryset = self.model.objects.all()
            # 表头展示
            header_list = []
            for field_or_func in self.get_new_list():
                if isinstance(field_or_func,str):
                    if field_or_func == '__str__': #当用户没有指定list_display 默认展示当前表的大写名字
                        val = self.model._meta.model_name.upper()
                    else:
                        val = self.model._meta.get_field(field_or_func).verbose_name
                else:
                    val = field_or_func(self,is_header=True)
                header_list.append(val)
            #表单展示
            body_list = [] #格式定义 [[obj1.title,obj1.price],[obj2.title,obj2.price],[]]
    
            for obj in queryset:
                tmp = []
                for field_or_func in self.get_new_list():#注意这里的list_display查找顺序,先查自己的,在查全局的,然后循环要展示的字段
                    if isinstance(field_or_func,str):
                        val = getattr(obj,field_or_func) #通过反射获取obj对象中field字段所对应的值
                    else:
                        val = field_or_func(self)
                    tmp.append(val)
    
                body_list.append(tmp)
    
    
            return render(request,'stark/list_view.html',locals())
    
        def add_view(self, request):
            return HttpResponse('add')
    
        def edit_view(self, request, id):
            return HttpResponse('edit')
    
        def delete_view(self, request, id):
            return HttpResponse('delete')
        @property
        def urls(self): #此处的self是指配置类对象
            tmp = [
                url(r'^$',self.list_view),
                url(r'^add/',self.add_view),
                url(r'^edit/(d+)/',self.edit_view),
                url(r'^delete/(d+)/',self.delete_view),
            ]
    
            return tmp,None,None
    class StarkSite(object):
        def __init__(self, name='admin'):
            self._registry = {}  # model_class class -> admin_class instance
    
        def register(self, model, admin_class=None, **options):
            if not admin_class:
                admin_class = ModelStark
            self._registry[model] = admin_class(model)
        def test(self,request):
            return HttpResponse('test')
        def get_urls(self):
            #先定义一个列表,因为要给调用者返回列表
            tmp = []
            #循环字典_registry
            for model_class,config_obj in self._registry.items():
                # print(model_class) #<class 'app01.models.Author'> 类字符串
                # print(config_obj) #<stark.service.stark.ModelStark object at 0x000001A79CC58C18> 配置类对象
    
                #获得模型表所在的应用名
                app_label = model_class._meta.app_label
                # 获得模型表对应的字符串名
                model_name = model_class._meta.model_name
                tmp.append(
                    url(r'^%s/%s/'%(app_label,model_name),config_obj.urls)
                )
            return tmp
        @property
        def urls(self):
            return self.get_urls(), None, None
    
    site = StarkSite()

      ##反向解析

    1、二级urls取别名:
        def __init__(self,model):
            self.model = model #self.model是指拿到当前对象所对应的模型表名,即四张表对应都不一样
            self.app_label = self.model._meta.app_label  #直接给对象初始化应用名
            self.model_name = self.model._meta.model_name #直接给对象初始化表名
         @property
        def urls(self): #此处的self是指配置类对象
            tmp = [
                url(r'^$',self.list_view,name="%s_%s_%s"%(self.app_label,self.model_name,'list')),#应用名+表明+操作
                url(r'^add/',self.add_view,name="%s_%s_%s"%(self.app_label,self.model_name,'add')),
                url(r'^edit/(d+)/',self.edit_view,name="%s_%s_%s"%(self.app_label,self.model_name,'edit')),
                url(r'^delete/(d+)/',self.delete_view,name="%s_%s_%s"%(self.app_label,self.model_name,'delete')),
            ]
    2、后端用到 reserse  obj为一个对象,因为编辑和删除时需要用到id,在访问的url链接中也会拼接一个id,所以再表单渲染那执行函数的时候传入obj
            def get_reverse_url(self,type,obj=None):
                if obj:
                    _url = reverse("%s_%s_%s" % (self.app_label, self.model_name, type), args=(obj.pk,))
                else:
                    _url = reverse("%s_%s_%s" % (self.app_label, self.model_name, type))
                return _url
                
            def edit_col(self,is_header=False,obj=None):
                if is_header:
                    return '编辑'
                _url = self.get_reverse_url('edit',obj)
                return mark_safe('<a href="%s">编辑</a>'%_url)
    
            def delete_col(self,is_header=False,obj=None):
                if is_header:
                    return '删除'
                _url =  self.get_reverse_url('delete',obj)
                return mark_safe('<a href="%s">删除</a>'%_url)
    3、函数根据参数传入的不同返回不同的结果
  • 相关阅读:
    Chapter 8. 面向对象(类库、委托)
    Chapter 8. 面向对象(多态--接口)
    练习:C# -- 多态
    Chapter 8. 面向对象(多态--抽象类)
    Chapter 8. 面向对象(多态--虚方法)
    Chapter 8. 面向对象(继承)
    Chapter 8. 面向对象(封装)
    Chapter 8. 面向对象(类、对象、字段、方法、属性、构造函数)
    练习、C# 结构体、冒泡排序
    1月19日(HTML之旅) CSS样式表
  • 原文地址:https://www.cnblogs.com/liangzhenghong/p/11285293.html
Copyright © 2020-2023  润新知