首页 技术 正文
技术 2022年11月21日
0 收藏 436 点赞 3,783 浏览 13125 个字

开始今日份整理

1.stark模块基本操作

1.1 stark模块的启动

保证django自动的加载每一个app下的stark.py文件

  • 创建django项目,创建stark项目,start app stark
  • settings注册app
  • stark.app中的apps.py创建def(函数名必须是ready才会自动执行)
from django.utils.module_loading import autodiscover_modulesclass StarkConfig(AppConfig):
name = 'stark'
def ready(self):
autodiscover_modules('stark')

Django-CRM项目学习(二)-模仿admin实现stark

1.2 stark模块的注册

所谓注册就是仿照admin模块,对于注册的数据表进行记录,方便后面的url的增删改查

仿照admin在stark下创建一个包services,并创建一个sites.py文件,代码如下

from django.contrib import admin
from django.urls import path
from django.shortcuts import render,HttpResponseclass ModelStark(object): list_display =("__str__") def __init__(self,model):
self.model = model def list_view(self, request): return render(request,'stark/list_view.html',locals()) def add_view(self, request):
return HttpResponse("add_view") def change_view(self, request, id):
return HttpResponse("change_view") def delete_view(self, request, id):
return HttpResponse("delete_view") @property
def get_url(self,):
temp = [
path("", self.list_view),
path("add/",self. add_view),
path("(\d+)/change/", self.change_view),
path("(\d+)/delete/", self.delete_view),
]
return (temp, None, None)class StarkSite:
def __init__(self):
self._registry ={} def register(self,model,admin_class=None,**options):
admin_class = admin_class or ModelStark
self._registry[model]=admin_class(model) def get_urls(self):
temp =[] # 拿到已经注册的所有表
for model,config_obj in self._registry.items():
# 表名
model_name = model._meta.model_name
# 项目名
model_label = model._meta.app_label temp.append(
path("%s/%s/"%(model_label,model_name),config_obj.get_url)
)
return temp @property
def urls(self):
return self.get_urls(),None,Nonesite = StarkSite()

在app01中创建stark.py文件,并注册

from stark.services.sites import site,ModelStark
from .models import Book,Publish,Author,Author_detail# 分别注册书籍,出版社以及作者
site.register(Book)
site.register(Publish)
site.register(Author)print(site._registry)

打印注册的列表,结果如下

{<class 'app01.models.Publish'>: <stark.services.sites.ModelStark object at 0x04B66B50>, <class 'app01.models.Book'>: <stark.services.sites.ModelStark object at 0x04B669B0>, <class 'app01.models.Author'>: <stark.services.sites.ModelStark object at 0x04B66970>}

这样就注册成功了

1.3 URL的分发功能以及页面样式理解(非常重要)

为了自定义的URL。所以我们才会有自定义页面,才会有配置类。

(1)在site中StarkSite类中创建一个URLS(self)方法,用@property方式,静态方法

Django-CRM项目学习(二)-模仿admin实现stark

(2)将二级分发功能放在配置类模块中

Django-CRM项目学习(二)-模仿admin实现stark

(3)配置类中self以及self.model的区别(超级重要)

self:是配置类对象

Django-CRM项目学习(二)-模仿admin实现stark

self.model:数据表对象,其实就是数据表的数据

通过上面:即可理解为什么在注册的时候有一个空字典,在每一个表对象进行注册时,对每一个表生成对应的配置类对象,如果一个表对象有自己的自定义样式,则会走自己自定义样式,无则会走默认样式。

这样就基本实现了url的分发功能,有一级也有二级分发。这块内容就是理解就会觉得东西少,不理解则东西好多!,只需要记住

self是配置类,self.model就是数据表对象就可以了。

对于默认类,self为默认配置类,其中self.model为传入的表对象,展示则使用默认类中的样式。

对于自定义类,self为自定义类,其中self.model为传入的表对象,自定义类继承默认类,优先使用自定义定义的类方法。

如下图展示

Django-CRM项目学习(二)-模仿admin实现starkDjango-CRM项目学习(二)-模仿admin实现stark

from django.contrib import admin
from django.urls import path
from django.shortcuts import render,HttpResponseclass ModelStark(object): list_display =("__str__") def __init__(self,model):
self.model = model def list_view(self, request): return render(request,'stark/list_view.html',locals()) def add_view(self, request):
return HttpResponse("add_view") def change_view(self, request, id):
return HttpResponse("change_view") def delete_view(self, request, id):
return HttpResponse("delete_view") @property
def get_url(self,):
temp = [
path("", self.list_view),
path("add/",self. add_view),
path("(\d+)/change/", self.change_view),
path("(\d+)/delete/", self.delete_view),
]
return (temp, None, None)class StarkSite:
def __init__(self):
self._registry ={} def register(self,model,admin_class=None,**options):
admin_class = admin_class or ModelStark
self._registry[model]=admin_class(model) def get_urls(self):
temp =[] # 拿到已经注册的所有表
for model,config_obj in self._registry.items():
# 表名
model_name = model._meta.model_name
# 项目名
model_label = model._meta.app_label
temp.append(
path("%s/%s/"%(model_label,model_name),config_obj.get_url)
)
return temp
@property
def urls(self):
return self.get_urls(),None,Nonesite = StarkSite()

stark核心代码

访问顺序

path("stark/app01/book",BookConfig(Book).list_view)
path("stark/app01/book/add",BookConfig(Book).add_view)
path("stark/app01/publish",ModelAdmin(Publish).list_view)
path("stark/app01/publish/add",ModelAdmin(Publish).add_view)

2.stark基础页面

2.1 stark的数据展示

2.1.1 普通数据与一对多数据展示

2.1.1.1 基于自定义类的数据展示

普通数据就是类似于数据库中book表中的title,price,出版日期,作者等基础数据,django天然对一对多支持

#目标数据类型
new_data=[
["python",123],
["java",234]
]

视图层如下

def list_view(self, request):
"""
self:当前配置类
self.model:当前访问的表数据
:param request:
:return:
"""
# 当前要展示的数据表的数据
querset = self.model.objects.all()
print(querset) print(self.list_display) # 用于构建视图中的展示数据
new_data = []
for obj in querset:
temp = []
# 构建列表嵌套中的小列表,使用的是自定义配置列表中要展示的内容
for field_or_info in self.list_display:
vim = getattr(obj,field_or_info)
temp.append(vim) new_data.append(temp)
print('new_data', new_data) return render(request,'stark/list_view.html',locals())

模板层如下

Django-CRM项目学习(二)-模仿admin实现stark

对于Book表,是自定义展示配置类,展示如下图

Django-CRM项目学习(二)-模仿admin实现stark

2.1.1.2 基于默认类的数据展示

视图层以及模板层如上,不过需要注意的是

Django-CRM项目学习(二)-模仿admin实现stark

没有加逗号,django会默认认为是一个字符串,并不会以一个元祖来读取元素,最后导致报错

对于出版社展示如下,只会展示对象名,显示名称是由于模型类中有__str__方法

Django-CRM项目学习(二)-模仿admin实现stark

2.1.2 多对多数据的判断

在app01中添加展示列表中添加作者这个多对多字段

2.1.2.1 错误显示

添加多对多字段

Django-CRM项目学习(二)-模仿admin实现stark

模板展示

Django-CRM项目学习(二)-模仿admin实现stark

最后展示中,作者多对多数据显示为none,

2.1.2.2 多对多数据判断以及自定义错误报错

(1)知识补充:

使用名字访问一个model的实例:模型名._meta.get_field(“publish”)

Django-CRM项目学习(二)-模仿admin实现stark

展示模型类的的名字:模型名._meta.model_name

Django-CRM项目学习(二)-模仿admin实现stark

展示模型类对应的项目名称:模型名._meta.app_label

Django-CRM项目学习(二)-模仿admin实现stark

展示一个模型类对象的默认名称:模型对象.verbose_name

Django-CRM项目学习(二)-模仿admin实现stark

对于模型类中的参数,如果设置了verbose.name则会显示设置的名字,无则显示参数名称

Django-CRM项目学习(二)-模仿admin实现stark

Django-CRM项目学习(二)-模仿admin实现stark

(2)多对多的判断

对于多对多的判断,首先是导包,对于 list_display来说,普通属性从self.list_display拿到的是字符串,一对多和多对多则是拿到的对象,拿到对象的类型判断是否是多对多,如果是多对多则报错并报错

Django-CRM项目学习(二)-模仿admin实现stark

对于多对多来说,需要提示为多对多,需要使用自定义列,弹出错误,用于提示错误

Django-CRM项目学习(二)-模仿admin实现stark

2.1.3 模型类中choice数据的反射

数据的反射,例如book的出版状态只有已出版以及未出版,但在数据库中记录只有1和2,需要对1和2的内容取出并反射出具体的内容

Django-CRM项目学习(二)-模仿admin实现stark

Django-CRM项目学习(二)-模仿admin实现stark

注:这里主要使用的是”get_属性名_display方法”,这样最后在页面中展示就会变成以及出版或者是未出版,不在是数据库中1和2

2.1.4 模型类属性中的__str__处理方法

field_obj = self.model._meta.get_field(field_or_func) #获取模型对象
这句话,获取的是模型类中的方法,由于模型类中没有__str__方法,所以需要对其进行处理

Django-CRM项目学习(二)-模仿admin实现stark

2.1.5 自定义的展示多对多内容

2.1.5.1 APP内对stark进行自定义列设定

自定义函数,例如show_author,然后把函数名丢到list_display列表中

Django-CRM项目学习(二)-模仿admin实现stark

stites中获取返回值,然后加入到列表中传到前端

注:由于list_display中有字符串也有函数,所以需要用到callable来判断是都为函数名

这里的self 是类函数调用的方式.,因为原来类中需要穿参,现在增加一个参数而已,什么都行.但是最好是self

Django-CRM项目学习(二)-模仿admin实现stark

2.1.5.2 处理多对多内容

在callable 内容中传入obj对象,方便操作数据

Django-CRM项目学习(二)-模仿admin实现stark

在自定制配置类中,通过obj 获取对应的作者信息

Django-CRM项目学习(二)-模仿admin实现stark

2.2 表头数据的展示

2.2.1 默认配置类

非定制列 ,即只有 __str__,只需要返回到数据表名的大写即可

Django-CRM项目学习(二)-模仿admin实现stark

2.2.2 自定制配置类

如果是普通属性,则只需要丢到对应的head_list列表中即可,对于自定义列,传入为函数名的时候则需要对传入做判断

Django-CRM项目学习(二)-模仿admin实现stark

app中注册类书写

Django-CRM项目学习(二)-模仿admin实现stark

2.3 添加选择框,编辑以及删除到所有的展示页面中

2.3.1 在html中展示指定的内容

导入mark_safe包

from django.utils.safestring import mark_safe

可以是后台传入的标签内容不会被转化,直接成为前端代码

2.3.2 反向解析

导入包

from django.urls import reverse

定义类名以及表名

def __init__(self,model):        self.model = model
self.model_name = self.model._meta.model_name
self.app_label = self.model._meta.app_label

视图层反向解析,设置name

@property
def get_url(self,):
# temp = [
# path("", self.list_view),
# path("add/",self. add_view),
# re_path("(\d+)/change/", self.change_view),
# re_path("(\d+)/delete/", self.delete_view),
# ]
temp = [
path("", self.list_view, name="%s_%s_list" % (self.app_label, self.model_name)),
path("add/", self.add_view, name="%s_%s_add" % (self.app_label, self.model_name)),
re_path("(\d+)/change/", self.change_view, name="%s_%s_change" % (self.app_label, self.model_name)),
re_path("(\d+)/delete/", self.delete_view, name="%s_%s_delete" % (self.app_label, self.model_name)),
]
return (temp, None, None)

反向解析代码

# 反向解析当前访问表的增删改查URL
def get_list_url(self):
# 反向解析当前表的查询的URL
list_url = reverse("%s_%s_list" % (self.app_label, self.model_name))
return list_url def get_add_url(self, obj):
# 反向解析当前表的添加的URL
add_url = reverse("%s_%s_delete" % (self.app_label, self.model_name))
return add_url def get_delete_url(self, obj):
# 反向解析当前表的删除的URL
delete_url = reverse("%s_%s_delete" % (self.app_label, self.model_name), args=(obj.pk,))
return delete_url def get_change_url(self, obj):
# 反向解析当前表的修改的URL
change_url = reverse("%s_%s_change" % (self.app_label, self.model_name), args=(obj.pk,))
return change_url

分析:反向解析名字为app名加表名,利用的是无名分组,注意无名分组为元祖传参,最后是三个默认列代码

# 三个默认列
# 选择框
def show_checkbox(self, obj=None, heade=False):
if heade:
return mark_safe("<input type='checkbox'>")
return mark_safe("<input type='checkbox'>") # 删除框 def show_delbtn(self, obj=None, heade=False):
if heade:
return '删除'
# return mark_safe("<a href='stark/app01/book/%s/delete'>删除</a>" % obj.pk)
return mark_safe("<a href='%s'>删除</a>" % self.get_delete_url(obj))
# 编辑框 def show_editbtn(self, obj=None, heade=False):
if heade:
return '编辑'
# return mark_safe("<a href='stark/app01/book/%s/change'>编辑</a>" % obj.pk)
return mark_safe("<a href='%s'>编辑</a>" % self.get_change_url(obj))####同时构建新的list_display,如果需要在默认列表中都展示,需要设定新的list_display # 构建新的list_display def get_new_list_display(self):
temp = []
temp.extend(self.list_display)
temp.append(ModelStark.show_editbtn)
temp.append(ModelStark.show_delbtn)
temp.insert(0, ModelStark.show_checkbox) return temp

属性说明:

Django-CRM项目学习(二)-模仿admin实现stark

  • self 为当前操作的模型配置类
  • obj=None 让默认对象的值为None,即当获取表头的时候不用传值
  • header=False  让默认的header 为False ,使调用数据的时候不用传值,不返回表头,只返回数据

Django-CRM项目学习(二)-模仿admin实现stark

获取表头中,是header =true 这样可以获取表头数据内容

完整site代码如下

from django.contrib import admin
from django.urls import path,re_path
from django.shortcuts import render,HttpResponse
from django.utils.safestring import mark_safe
from django.urls import reverseclass ModelStark(object): list_display =("__str__",) def __init__(self,model): self.model = model
self.model_name = self.model._meta.model_name
self.app_label = self.model._meta.app_label # 反向解析当前访问表的增删改查URL
def get_list_url(self):
# 反向解析当前表的查询的URL
list_url = reverse("%s_%s_list" % (self.app_label, self.model_name))
return list_url def get_add_url(self, obj):
# 反向解析当前表的添加的URL
add_url = reverse("%s_%s_delete" % (self.app_label, self.model_name))
return add_url def get_delete_url(self, obj):
# 反向解析当前表的删除的URL
delete_url = reverse("%s_%s_delete" % (self.app_label, self.model_name), args=(obj.pk,))
return delete_url def get_change_url(self, obj):
# 反向解析当前表的修改的URL
change_url = reverse("%s_%s_change" % (self.app_label, self.model_name), args=(obj.pk,))
return change_url # 三个默认列
# 选择框
def show_checkbox(self, obj=None, heade=False):
if heade:
return mark_safe("<input type='checkbox'>")
return mark_safe("<input type='checkbox'>") # 删除框 def show_delbtn(self, obj=None, heade=False):
if heade:
return '删除'
# return mark_safe("<a href='stark/app01/book/%s/delete'>删除</a>" % obj.pk)
return mark_safe("<a href='%s'>删除</a>" % self.get_delete_url(obj))
# 编辑框 def show_editbtn(self, obj=None, heade=False):
if heade:
return '编辑'
# return mark_safe("<a href='stark/app01/book/%s/change'>编辑</a>" % obj.pk)
return mark_safe("<a href='%s'>编辑</a>" % self.get_change_url(obj))
# 构建新的list_display def get_new_list_display(self):
temp = []
temp.extend(self.list_display)
temp.append(ModelStark.show_editbtn)
temp.append(ModelStark.show_delbtn)
temp.insert(0, ModelStark.show_checkbox) return temp # 视图函数
def list_view(self, request):
"""
self:当前配置类
selfmodel:当前访问的表数据
:param request:
:return:
"""
# 当前访问表的数据
querset = self.model.objects.all()
print(querset) print(self.list_display) #用于展示头部文件
header_list=[]
for field_or_info in self.get_new_list_display():
#判断是函数名或者是字符段
if callable(field_or_info):
vim=field_or_info(self,heade=True)
header_list.append(vim)
else:
# 获取指定字段的对象属性,并拿出verbose_name属性
if field_or_info=='__str__':
#如果只有默认装饰类,只有__str__,则拿出他的表名作为头
vim = self.model._meta.model_name.upper()
else:
file_obj =self.model._meta.get_field(field_or_info)
vim = file_obj.verbose_name
header_list.append(vim) #用于构建视图中的展示数据
new_data=[]
for obj in querset:
temp=[]
for field_or_info in self.get_new_list_display():
# 判断是函数还是字符段
if callable(field_or_info):
vim = field_or_info(self,obj)
else:
try:
from django.db.models.fields.related import ManyToManyField
info_obj=self.model._meta.get_field(field_or_info)
# 判断多对多字段
if type(info_obj)==ManyToManyField:
raise Exception("list_distplay 不能是多不多字段")
#判断是否是__str__
# if field_or_info=='__str':
# vim=getattr(obj,field_or_info)()
# 判断是否有choices字段
if info_obj.choices:
vim = getattr(obj,'get_%s_display'%field_or_info)()
else:
vim =getattr(obj,field_or_info)
except Exception as e:
vim = getattr(obj, field_or_info)()
temp.append(vim)
new_data.append(temp)
print('new_data',new_data) # 目标数据
# new_data=[
# ["python",123],
# ["java",234]
# ] return render(request,'stark/list_view.html',locals()) def add_view(self, request):
return HttpResponse("add_view") def change_view(self, request, id):
return HttpResponse("change_view") def delete_view(self, request, id):
return HttpResponse("delete_view") @property
def get_url(self,):
# temp = [
# path("", self.list_view),
# path("add/",self. add_view),
# re_path("(\d+)/change/", self.change_view),
# re_path("(\d+)/delete/", self.delete_view),
# ]
temp = [
path("", self.list_view, name="%s_%s_list" % (self.app_label, self.model_name)),
path("add/", self.add_view, name="%s_%s_add" % (self.app_label, self.model_name)),
re_path("(\d+)/change/", self.change_view, name="%s_%s_change" % (self.app_label, self.model_name)),
re_path("(\d+)/delete/", self.delete_view, name="%s_%s_delete" % (self.app_label, self.model_name)),
]
return (temp, None, None)class StarkSite:
def __init__(self):
self._registry ={} def register(self,model,admin_class=None,**options):
admin_class = admin_class or ModelStark
self._registry[model]=admin_class(model) def get_urls(self):
temp =[] # 拿到已经注册的所有表
for model,config_obj in self._registry.items():
# 表名
model_name = model._meta.model_name
# 项目名
model_label = model._meta.app_label
temp.append(
path("%s/%s/"%(model_label,model_name),config_obj.get_url)
)
return temp
@property
def urls(self):
return self.get_urls(),None,Nonesite = StarkSite()

site代码

完整注册stark代码如下

from stark.services.sites import site,ModelStark
from .models import *
from django.utils.safestring import mark_safeclass BookConfig(ModelStark): def show_authors(self,obj=None,heade=False):
if heade:
return "作者信息" return " ".join([author.name for author in obj.author.all()])
# # 选择框
# def show_checkbox(self,obj=None,heade=False):
# if heade:
# return mark_safe("<input type='checkbox'>")
# return mark_safe("<input type='checkbox'>")
#
# # 删除框
# def show_delbtn(self, obj=None, heade=False):
# if heade:
# return '删除'
# return mark_safe("<a href='stark/app01/book/%s/delete'>删除</a>"%obj.pk)
#
# # 编辑框
# def show_editbtn(self, obj=None, heade=False):
# if heade:
# return '编辑'
# return mark_safe("<a href='stark/app01/book/%s/change'>编辑</a>" % obj.pk) list_display=["title","price","staes","publish",show_authors]
# list_display=["title","price","staes","publish"]site.register(Book,BookConfig)
site.register(Publish)
print(site._registry)

stark代码

a

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,105
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,582
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,429
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,836
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,919