仿照admin写一个startk组件
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',
]
urls.py
from stark.sites import site
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^stark/', site.urls),
]
stark/apps.py
from django.utils.module_loading import autodiscover_modules class StarkConfig(AppConfig):
name = 'stark' def ready(self):
autodiscover_modules('stark')
stark/sites.py
from django.utils.safestring import mark_safe
from django.shortcuts import HttpResponse,render,redirect
from django.core.urlresolvers import reverse
from django.forms import ModelForm
class DataList:
def __init__(self,config,obj_list):
self.config=config
self.obj_list=obj_list
def get_header_list(self):
header_list = []
for i in self.config.new_list_display():
if isinstance(i, str):
if i == "__str__":
val = self.config.model._meta.model_name.upper()
else:
filed_obj = self.config.model._meta.get_field(i)
val = filed_obj.verbose_name
else:
val = i(is_header=True)
header_list.append(val)
return header_list
def get_body_list(self):
new_data_list = []
for obj in self.obj_list:
tmp = []
for filed in self.config.new_list_display():
if isinstance(filed, str):
try:
from django.db.models.fields.related import ManyToManyField
filed_obj = self.config.model._meta.get_field(filed)
if isinstance(filed_obj, ManyToManyField):
li = []
for i in getattr(obj, filed).all():
li.append(str(i))
val = ",".join(li)
else:
val = getattr(obj, filed)
except Exception as e:
val = getattr(obj, filed)
else:
val = filed(obj=obj)
tmp.append(val)
new_data_list.append(tmp)
return new_data_list class ModelStark: list_display = ('__str__',)
search_fields=[]
actions=[]
def __init__(self,model,site):
self.model=model
self.site=site def edit(self,is_header=False,obj=None):
if is_header:
return "操作"
info = self.model._meta.app_label, self.model._meta.model_name
return mark_safe('<a class="btn btn-warning" href="%s">编辑</a>'%reverse('%s_%s_change'%info,args=(obj.pk,))) def delete(self,is_header=False,obj=None):
if is_header:
return "操作"
info = self.model._meta.app_label, self.model._meta.model_name
return mark_safe('<a class="btn btn-danger" href="%s">删除</a>'%reverse('%s_%s_delete'%info,args=(obj.pk,))) def checkbox(self, obj=None, is_header=False):
if is_header:
return "选择"
return mark_safe("<input type='checkbox' name=checked_data value=%s>" % obj.pk) def new_list_display(self):
tmp=[]
tmp.append(self.checkbox)
tmp.extend(self.list_display)
tmp.append(self.edit)
tmp.append(self.delete)
return tmp def get_search_condition(self,request):
from django.db.models import Q
search_condition=Q()
search_condition.connector="or"
val=request.GET.get("q")
if val:
for field in self.search_fields:
search_condition.children.append((field+"__contains",val))
return search_condition def get_actions_list(self):
li=[]
for func in self.actions:
dic={}
dic["name"]=func.__name__
dic["desc"]=func.desc
li.append(dic)
return li def get_list_url(self):
info = self.model._meta.app_label, self.model._meta.model_name
return reverse('%s_%s_list'%info) def list_view(self,request):
if request.method=="POST":
print(request.POST)
action=request.POST.get("action")
checked_data=request.POST.getlist("checked_data")
action=getattr(self,action)
action(checked_data)
search_condition=self.get_search_condition(request)
from django.db.models import Q
filter_condition = Q()
for key, value in request.GET.items():
filter_condition.children.append((key, value))
obj_list = self.model.objects.all().filter(search_condition).filter(filter_condition)
data_list=DataList(self,obj_list)
return render(request, "list.html", locals()) def get_modelform(self):
from django.forms import ModelForm
class StarkModelForm(ModelForm):
class Meta:
model=self.model
fields="__all__"
return StarkModelForm def add_view(self,request): if request.method=="POST":
form= self.get_modelform()(request.POST) if form.is_valid():
form.save() return redirect(self.get_list_url())
else:
return render(request, "add.html", locals()) form=self.get_modelform()() return render(request, "add.html", locals())
def delete_view(self,request,nid):
if request.method == "POST":
self.model.objects.get(pk=nid).delete() return redirect(self.get_list_url())
url = self.get_list_url()
return render(request, "delete.html", locals()) def extra_url(self):
return [] def change_view(self,request,nid):
obj = self.model.objects.filter(pk=nid).first() if request.method == "POST":
form = self.get_modelform()(request.POST, instance=obj) if form.is_valid():
form.save() return redirect(self.get_list_url()) form = self.get_modelform()(instance=obj) return render(request, "change.html", locals()) @property
def get_url2(self):
from django.conf.urls import url
info = self.model._meta.app_label, self.model._meta.model_name
urlpatterns = [
url(r'^$', self.list_view, name='%s_%s_list' % info),
url(r'^add/$', self.add_view, name='%s_%s_add' % info),
url(r'^(\d+)/delete/$', self.delete_view, name='%s_%s_delete' % info),
url(r'^(\d+)/change/$', self.change_view, name='%s_%s_change' % info),
]
return urlpatterns class StarkSite(object):
def __init__(self, name='stark'):
self._registry = {} # model_class class -> admin_class instance
self.name = name def register(self, model, admin_class=None, **options):
if not admin_class:
admin_class = ModelStark
self._registry[model] = admin_class(model, self) def get_url(self):
from django.conf.urls import url
urlpatterns=[]
for model,model_stark in self._registry.items():
urlpatterns+=[
url(r'^%s/%s/'%(model._meta.app_label, model._meta.model_name),(model_stark.get_url2,None,None)),
] return urlpatterns
@property
def urls(self):
return self.get_url(),None,None
site = StarkSite()
app01/models.py
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,verbose_name="姓名")
age = models.IntegerField(verbose_name="年龄") # 与AuthorDetail建立一对一的关系
authorDetail = models.OneToOneField(to="AuthorDetail") 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="价格")
keepNum = models.IntegerField()
commentNum = models.IntegerField() # 与Publish建立一对多的关系,外键字段建立在多的一方
publish = models.ForeignKey(to="Publish", to_field="nid",verbose_name="出版社") # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
authors = models.ManyToManyField(to='Author',verbose_name="作者") def __str__(self):
return self.title
app01/stark.py
from stark.sites import site,ModelStark
from .models import *
# Register your models here. class BookStark(ModelStark):
list_display = ("title","publishDate","price","publish","authors")
search_fields = ["title"] def patch_delete(self,selected_pk):
self.model.objects.filter(pk__in=selected_pk).delete()
patch_delete.desc="批量删除" actions=[patch_delete] site.register(Author)
site.register(AuthorDetail)
site.register(Publish)
site.register(Book,BookStark)
templates/list.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3>查看数据</h3> <div class="container">
<div class="row">
<div class="col-md-8"> {% if self.search_fields %}
<form class="form-inline pull-right" method="get" action="" style="margin-bottom: 10px">
{% else %}
<form class="form-inline pull-right hidden" method="get" action="" style="margin-bottom: 10px">
{% endif %} {% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" name="q">
</div>
<button type="submit" class="btn btn-default">搜索</button>
</form>
<form action="" method="post">
{% csrf_token %}
<select class="form-control pull-left" name="action" style="width: auto"> {% for action in self.get_actions_list %}
<option value="{{ action.name }}">{{ action.desc }}</option>
{% endfor %}
</select>
<input type="submit" class="btn btn-default" value="执行">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
{% for foo in data_list.get_header_list %}
<th>{{ foo }}</th>
{% endfor %} </tr>
</thead>
<tbody>
{% for new_data in data_list.get_body_list %}
<tr>
{% for foo in new_data %}
<td>{{ foo }}</td>
{% endfor %} </tr>
{% endfor %} </tbody>
</table>
</form> </div>
</div>
</div> </body>
</html>
templates/add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<style>
input[id], select {
display: block;
width: 100%;
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
</style>
</head>
<body> <h3>添加页面</h3> {% include 'form.html' %} </body>
</html>
templates/change.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<style>
input[id], select {
display: block;
width: 100%;
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
</style>
</head>
<body> <h3>编辑页面</h3> {% include 'form.html' %} </body>
</html>
templates/form.html
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-1"> <form action="" method="post" novalidate>
{% csrf_token %} {% for field in form %}
<div class="form-group">
<label for="">{{ field.label }}</label>
{{ field }} <span class="pull-right" style="color: red">{{ field.errors.0 }}</span>
</div>
{% endfor %} <input type="submit" class="btn btn-default">
</form> </div>
</div>
</div>
templates/delete.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head>
<body> <h3>删除页面</h3> <form action="" method="post">
{% csrf_token %}
<input type="submit" value="确认删除">
<a href="{{ url }}">取消</a>
</form> </body>
</html>
仿照admin写一个startk组件的更多相关文章
- 仿照admin的stark自定义组件的功能实现
仿照admin的stark自定义组件的功能实现:其中最主要的就是增删改查的实现 1.查:首先页面中显示表头和数据,都是动态的,而不是写死的. (1) 先看表头和表单数据:这个是查看的视图函数,但是为了 ...
- 写一个vue组件
写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...
- js单行写一个评级组件
单行写一个评级组件:"★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate); -----------------------------------分隔符- ...
- 表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这种写法就是把组件嵌套改为配置方式
表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这 ...
- Vue3语法快速入门以及写一个倒计时组件
Vue3写一个倒计时组件 vue3 beta版本发布已有一段时间了,文档也大概看了一下,不过对于学一门技术,最好的方法还是实战,于是找了一个比较简单的组件用vue3来实现,参考的是vant的count ...
- 仿照手机写一个WIFI的操作程序
本篇博客仿照手机的功能,写一个WIFI的操作程序. 手机的WIFI功能有哪些呢?当我们进入wlan的设置界面的时候,将自动识别出若干个wifi的热点,并且会自动更新,当点击某个wifi热点的时候,然后 ...
- [翻译]怎么写一个React组件库(一)
本文同步发布于知乎专栏 https://zhuanlan.zhihu.com/p/27401329,喜欢本文的就去知乎点个赞支持下吧- 引言 该系列文章将通过创建一个组件库来引导你学习如何构建自己的组 ...
- 仿照admin实现一个自定义的增删改查的组件
1.首先,创建三个项目,app01,app02,stark,在settings里边记得配置.然后举例:在app01的model里边写表,用的db.sqlite3,所以数据库不用再settings里边配 ...
- HTML+CSS+JS(+Vue)写一个通讯录组件
求各位大大的Star(*/ω\*). 没有录屏,所以上传的是图片.后面已补充录屏效果. 效果:(主要是参考小米Note3的通讯录的效果做的) 主要功能: 1. 滚动后,通讯录的模块标题会固定在顶部(图 ...
随机推荐
- 《转》 EJB到底是什么,真的那么神秘吗??
1. 我们不禁要问,什么是"服务集群"?什么是"企业级开发"? 既然说了EJB 是为了"服务集群"和"企业级开发",那么 ...
- 原创:项目管理的理论与实践 讲座的PPT
业余时间做的两个PPT,曾经给公司同事讲过,PPT内容毕竟还是不够全面,如果有不清楚的地方,欢迎提问 项目管理的理论与实践 虚拟案例-超市管理系统
- New Concept English three (40)
23w/m 48 errors It has never been explained why university students seem to enjoy practical jokes mo ...
- sphinx使用
一. 1.先得包含下载的文件 include'./sphinx/api/sphinxapi.php'; $sphinx= new SphinxClient(); $sphinx->SetServ ...
- ng 双向数据绑定
1.方向1:model->View模型数据绑定到视图 绑定的方式:①双花括号 ②常见的ng指令(ngRepeat ngIf ngShow....) 效果:数据一旦绑定到视图上,随着数据的修改,视 ...
- 人生苦短之我用Python篇(paramiko模块)
该模块机遇SSH用于连接远程服务器并执行相关操作 基于用户名密码连接: import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在kno ...
- 2018下C程序设计(上)第0次作业
1.翻阅邹欣老师博客关于师生关系博客,并回答下列问题: (1)大学和高中最大的不同是什么?请看大学理想的师生关系是?有何感想? 我认为大学和高中最大的不同在于我们(包括老师)对学习的态度.在高中,学生 ...
- windows 下后台启动 redis
1. 进入 DOS窗口 2. 在进入Redis的安装目录 3. 输入:redis-server --service-install redis.windows.conf --loglevel verb ...
- docx转doc时,防止公式被转成图片的解决办法
编辑社回复需要doc(Word 97-2003)格式的文档,可是将docx(Word 2007+)另存为doc格式时,发现公式被转成了图片.其实,最简单的办法就是,打个电话过去给编辑社:“大爷,拜托您 ...
- opencv之图像阈值化处理
一.函数简介 1.threshold-图像简单阈值化处理 函数原型:threshold(src, thresh, maxval, type, dst=None) src:图像矩阵 thresh:阈值 ...