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组件的更多相关文章

  1. 仿照admin的stark自定义组件的功能实现

    仿照admin的stark自定义组件的功能实现:其中最主要的就是增删改查的实现 1.查:首先页面中显示表头和数据,都是动态的,而不是写死的. (1) 先看表头和表单数据:这个是查看的视图函数,但是为了 ...

  2. 写一个vue组件

    写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件 ...

  3. js单行写一个评级组件

    单行写一个评级组件:"★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate); -----------------------------------分隔符- ...

  4. 表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这种写法就是把组件嵌套改为配置方式

    表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这 ...

  5. Vue3语法快速入门以及写一个倒计时组件

    Vue3写一个倒计时组件 vue3 beta版本发布已有一段时间了,文档也大概看了一下,不过对于学一门技术,最好的方法还是实战,于是找了一个比较简单的组件用vue3来实现,参考的是vant的count ...

  6. 仿照手机写一个WIFI的操作程序

    本篇博客仿照手机的功能,写一个WIFI的操作程序. 手机的WIFI功能有哪些呢?当我们进入wlan的设置界面的时候,将自动识别出若干个wifi的热点,并且会自动更新,当点击某个wifi热点的时候,然后 ...

  7. [翻译]怎么写一个React组件库(一)

    本文同步发布于知乎专栏 https://zhuanlan.zhihu.com/p/27401329,喜欢本文的就去知乎点个赞支持下吧- 引言 该系列文章将通过创建一个组件库来引导你学习如何构建自己的组 ...

  8. 仿照admin实现一个自定义的增删改查的组件

    1.首先,创建三个项目,app01,app02,stark,在settings里边记得配置.然后举例:在app01的model里边写表,用的db.sqlite3,所以数据库不用再settings里边配 ...

  9. HTML+CSS+JS(+Vue)写一个通讯录组件

    求各位大大的Star(*/ω\*). 没有录屏,所以上传的是图片.后面已补充录屏效果. 效果:(主要是参考小米Note3的通讯录的效果做的) 主要功能: 1. 滚动后,通讯录的模块标题会固定在顶部(图 ...

随机推荐

  1. LeetCode OJ:Permutations II(排列II)

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  2. DMD数字微镜

    Digital Micromirror Device DMD技术于1987年被发明,到1996年春走向市场.DMD是一个真正的微光机电系统(MOEMS),该器件是利用CMOS工艺和微机械加工(MEMS ...

  3. java-正则表达式判断手机号

    要更加准确的匹配手机号码只匹配11位数字是不够的,比如说就没有以144开始的号码段, 故先要整清楚现在已经开放了多少个号码段,国家号码段分配如下: 移动:134.135.136.137.138.139 ...

  4. Java一般要学多久?

    其实学java一般要多久?因人而异,有些人资质好,头脑聪明几个月就能学会,有些人天生愚钝,理解能力差,不过勤能补拙,只是时间相对长点 要坚持住.不过java相对于C,C++java而言,java无疑简 ...

  5. 使用Hydra通过ssh破解密码

    Hydra是非常高效的网络登录破解工具,它可以对多种服务程序执行暴力破解(SSH.VNC等等). 防止这种攻击其实很容易,方法很多.以SSH为例: Ubuntu:使用Port Knocking隐藏SS ...

  6. Apache中 RewriteCond 规则参数介绍 转

    摘要: RewriteCond指令定义了规则生效的条件,即在一个RewriteRule指令之前可以有一个或多个RewriteCond指令.条件之后的重写规则仅在当前URI与Pattern匹配并且满足此 ...

  7. Linux部分常用命令学习(一)

    什么是linux命令? 是一个可执行程序,就像我们所看到的位于目录/usr/bin 中的文件一样. 属于这一类的程序,可以编译成二进制文件,诸如用 C 和 C++语言写成的程序, 也可以是由脚本语言写 ...

  8. 洛谷 P1262 间谍网络

    传送门 题目大意:A能揭发B,B能揭发C..某些人可以被收买,如果收买A,那么A,B,C..的情报都可以得到. 求能否得到所有情报,如果可以最少花费多少钱去收买. 题解:tajian缩点 dfs/bf ...

  9. k8s api server ha 连接配置问题

    常见的lb 负载有硬件的f5 big-ip  ,同时对于互联网公司大家常用的是nginx  haproxy 了解k8s 集群高可用的都知道 api server  是无状态的(etcd 解决了),但是 ...

  10. bzoj 4556 字符串 —— 后缀数组+主席树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4556 就是找一个 rk 在一段区间内的前驱和后继: 由于 LCP 还有区间长度的限制,所以可 ...