仿照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>

原文地址:https://www.cnblogs.com/guoyunlong666/p/9241563.html

时间: 2024-08-29 17:11:31

仿照admin写一个startk组件的相关文章

写一个vue组件

写一个vue组件 我下面写的是以.vue结尾的单文件组件的写法,是基于webpack构建的项目.如果还不知道怎么用webpack构建一个vue的工程的,可以移步到vue-cli. 一个完整的vue组件会包括一下三个部分: template:模板 js: 逻辑 css : 样式 每个组件都有属于自己的模板,js和样式.如果将一个页面比喻成一间房子的话,组件就是房子里的客厅.卧室.厨房.厕所.如果把厨房单独拿出来的话,组件又可以是刀.油烟机...等等.就是说页面是由组件构成的,而组件也可以是组件构成

在React中写一个Animation组件,为组件进入和离开加上动画/过度

问题 在单页面应用中,我们经常需要给路由的切换或者元素的挂载和卸载加上过渡效果,为这么一个小功能引入第三方框架,实在有点小纠结.不如自己封装. 思路 原理 以进入时opacity: 0 --> opacity: 1 ,退出时opacity: 0 --> opacity: 1为例 元素挂载时 挂载元素dom 设置动画opacity: 0 --> opacity: 1 元素卸载时 设置动画opacity: 0 --> opacity: 1 动画结束后卸载dom 组件设计 为了使得组件简

React Native学习(四)—— 写一个公用组件(头部)

本文基于React Native 0.52 Demo上传到Git了,有需要可以看看,写了新内容会上传的.Git地址 https://github.com/gingerJY/React-Native-Demo 一.总览 头部通常分为左.中.右三部分,效果图如下: 二.头部组件 1.创建components文件夹,新建commonHead.js 2.commonHead.js 头部分为左.中.右三块,我们需要提供接口,获取外部传入的值,从而判断哪一块需要创建. static propTypes =

利用React写一个评论区组件(React初探)

本文是在阅读学习了官方的React Tutorial之后的整理,实例链接. 开始使用React 首先从官方获取React.js的最新版本(v0.12.2),或者下载官方的Starter Kit,并在我们的html中引入它们: <head> <meta charset="UTF-8"> <title>React Test Page</title> <script src="../build/react.js">

手把手写一个基于Spring Boot框架下的参数校验组件

手把手写一个基于Spring Boot框架下的参数校验组件(JSR-303) 前言 之前参与的新开放平台研发的过程中,由于不同的接口需要对不同的入参进行校验,这就涉及到通用参数的校验封装,如果不进行封装,那么写出来的校验代码将会风格不统一.校验工具类不一致.维护风险高等其它因素,于是我对其公共的校验做了一个封装,达到了通过注解的方式即可实现参数统一校验. 遇到的问题                    在封装的时候就发现了一个问题,我们是开放平台,返回的报文都必须是统一风格,也就是类似于{co

假期跟我一起写一个点对点VPN-SimpleVPN详解

自从上周写了几篇关于BadVPN的文章后,收到很多的邮件前来询问细节.其中最多的不外乎两类,一类是询问怎么使用的,另一类则是要求我写几篇源码分析.先来一个一个说. 1.关于BadVPN的使用问题 和OpenVPN相反,BadVPN几乎没有除了配置隧道之外的任何东西,这些被排除了内容中最重要的应该就是路由了.OpenVPN中就有关于路由的很多配置,还可以从服务端往客户端推送路由,这简直太方便了,但同时也增加了配置的复杂性.BadVPN我认为是比较好的方式,它本身没有关于路由的任何配置,只要你把隧道

【转载】COM 组件设计与应用(五)——用 ATL 写第一个组件

原文:http://vckbase.com/index.php/wv/1215.html 一.前言 1.如果你在使用 vc5.0 及以前的版本,请你升级为 vc6.0 或 vc.net 2003: 2.如果你在使用 vc6.0 (ATL 3.0)请阅读本回内容: 3.如果你在使用 vc.net(ATL 7.0)请阅读下回内容:(当然读读本文内容也不错) 4.这第一个组件,除了所有 COM 组件必须的 IUnknown 接口外,我们再实现一个自己定义的接口 IFun,它有两个函数: Add()完成

【转载】COM 组件设计与应用(六)——用 ATL 写第一个组件

原文:http://vckbase.com/index.php/wv/1216.html 一.前言 1.与 <COM 组件设计与应用(五)>的内容基本一致.但本回讲解的是在 vc.net 2003 下的使用方法,即使你不再使用vc6.0,也请和上一回的内容,参照比对. 2.这第一个组件,除了所有 COM 组件必须的 IUnknown 接口外,我们再实现一个自己定义的接口 IFun,它有两个函数: Add()完成两个数值的加法,Cat()完成两个字符串的连接. 3.下面......好好听讲! 开

写一个ajax程序就是如此简单

写一个ajax程序就是如此简单 ajax介绍: 1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发技术.     2:基于web标准XHTML+CSS的表示:     3:使用 DOM进行动态显示及交互:     4:使用 XML 和 XSLT 进行数据交换及相关操作:     5:使用 XMLHttpRequest 进行异步数据查询.检索: 程序员应用ajax的途经: 1:.Net下的Ajax