• 仿照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',
    ]
    View Code

     urls.py

    from stark.sites import site
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^stark/', site.urls),
    ]
    View Code

    stark/apps.py

    from django.utils.module_loading import autodiscover_modules
    
    
    
    
    class StarkConfig(AppConfig):
        name = 'stark'
    
        def ready(self):
            autodiscover_modules('stark')
    View Code

    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()
    View Code

    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
    View Code

    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)
    View Code

    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=" 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>
    View Code

    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>
    View Code

    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>
    View Code

    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>
    View Code

    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>
    View Code
  • 相关阅读:
    Java之装饰模式
    Sharding-jdbc(一)分库分表理解
    JVM(四)JVM的双亲委派模型
    JVM(三)JVM的ClassLoader类加载器
    JVM(二)JVM的结构
    JVM(一)JVM的概述与运行流程
    Redis随笔(六)RESP的协议规范
    Redis随笔(五)Jedis、jedisCluster的使用
    Collections.synchronizedList使用方法陷阱(1)
    Collections.synchronizedList使用方法
  • 原文地址:https://www.cnblogs.com/guoyunlong666/p/9241563.html
Copyright © 2020-2023  润新知