9 stark组件 增删改

1、效果图

 

2、详细步骤解析

1、构造增删改查url,反向解析

2、ModelForm定制add、edit页面

 

 

 3、staradmin中的ModelForm

 

3、总结、代码

 1、知识点

1.解决代码重用
{% include 'form.html' %}

2.自定制配置modelform
每张表,就可自定义配置 labels , widges...
class BookModelForm(ModelForm):
class Meta:
model = Book
fields = "__all__"
labels = {
"title": '书籍名称',
"price": '价格',
}
...
modelform_class = BookModelForm


3、stark中的Modelform配置
modelform_class = []
# ModelForm组件渲染  list、增、删、改页面
def get_modelform_class(self):
"""ModelForm组件"""
if not self.modelform_class:
from django.forms import ModelForm
class ModelFormDemo(ModelForm):
class Meta:
model = self.model
fields = "__all__"
return ModelFormDemo
else:
return self.modelform_class

配置样式,由于不确定字段,得在前端玩!

4.change_view()
注意 instance,否则为添加
form = ModelFormDemo(request.POST, instance=edit_obj)
if form.is_valid():
form.save()

2、模板层代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block title %}
        <title>Title</title>
    {% endblock %}

    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    <script src="/static/jQuery/jquery-3.2.1.min.js"></script>
    {% block css %}

    {% endblock %}
</head>

<body>
<div class="container">
    <div class="row">
        {% block header %}

        {% endblock %}

        <div class="col-md-9 col-md-offset-1">
            {% block content %}

            {% endblock %}
        </div>
    </div>
</div>
{% block javascript %}

{% endblock %}
</body>
</html>
base.html
{% extends 'base.html' %}

{% block title %}
    <title>add页面</title>
{% endblock %}


{% block css %}
   <style type="text/css">
        input,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;
        }
        .error{
            color: red;
        }
    </style>
{% endblock %}

{% block header %}
    <h3>add页面</h3>
{% endblock %}

{% block content %}
  {% include 'form.html' %}
{% endblock %}
add_view.html
{% extends 'add_view.html' %}

{% block title %}
    <title>edit页面</title>
{% endblock %}


{% block header %}
    <h3>edit页面</h3>
{% endblock %}
change_view.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>删除页面</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    <script src="/static/jQuery/jquery-3.2.1.min.js"></script>
</head>

<body>
<div class="container">

    <form action="" method="post" class="text-center">
        {% csrf_token %}
        <p class="text-info">你确认要删除这条记录?</p>
        <button class="btn btn-danger">确认</button>
        <a href="{{ url }}" class="btn btn-primary">取消</a>
    </form>

</div>
</body>
</html>
delete_view.html
<form action="" method="post" novalidate>
    {% for field in form %}
        {% csrf_token %}
        <div class="form-group">
            <label for="">{{ field.label }}</label>
            {{ field }}
            <span class="error pull-right">{{ field.errors.0 }}</span>
        </div>
    {% endfor %}
    <br>
    <button class="btn btn-success pull-right">提交</button>
</form>
form.html
{% extends 'base.html' %}

{% block title %}
    <title>list页面</title>
{% endblock %}

{% block header %}
    <h3>list页面</h3>
{% endblock %}
{% block content %}
    <a class="btn btn-primary" href="{{ add_url }}">添加数据</a>
    <table class="table table-bordered table-striped">
        <tr>
            {% for header in header_list %}
                <th>{{ header }}</th>
            {% endfor %}
        </tr>

        {% for data in new_data_list %}
            <tr>
                {% for item in data %}
                    <td>{{ item }}</td>
                {% endfor %}

            </tr>
        {% endfor %}
    </table>
{% endblock %}


{% block javascript %}
    <script type="text/javascript">
        $('#choice').click(function () {
            if ($(this).prop('checked')) {   //对象自身属性中是否具有指定的属性
                $('.choice_item').prop("checked", true)
            } else {
                $('.choice_item').prop("checked", false)
            }
        })
    </script>
{% endblock %}
list_view.html

3、stark/service/stark.py

# -*- coding: utf-8 -*-
# @Time    : 2018/08/17 0017 14:46
# @Author  : Venicid
from django.conf.urls import url
from django.shortcuts import HttpResponse,render,redirect

from django.utils.safestring import mark_safe
from django.urls import reverse


class ModelStark(object):
    list_display = ["__str__"]  # 子类中没有,直接用父类自己的
    list_display_links = []

    modelform_class = []

    def __init__(self,model, site):
        self.model = model
        self.site = site

    # 增删改查url
    def get_add_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_add" %(app_label,model_name))
        return _url

    def get_list_url(self):
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_list" %(app_label,model_name))
        return _url


    # 复选框,编辑,删除
    def checkbox(self,obj=None, header=False):
        if header:
            return mark_safe("<input id='choice' type='checkbox'>")
        return mark_safe("<input class='choice_item' type='checkbox'>")


    def edit(self,obj=None, header=False):
        if header:
            return "操作"
        # 方案1:固定url
        # return mark_safe("<a href=/stark/app01/userinfo/%s/change>编辑</a>")
        # 方案2:拼接url
        # return mark_safe("<a href='%s/change'>编辑</a>")

        # 方案3:反向解析
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_change"%(app_label,model_name),args=(obj.pk,))
        # print("_url",_url)
        return mark_safe("<a href='%s'>编辑</a>"%_url)


    def deletes(self,obj=None, header=False):
        if header:
            return "操作"
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label
        _url = reverse("%s_%s_delete"%(app_label,model_name),args=(obj.pk,))
        return mark_safe("<a href='%s'>删除</a>"%_url)



    # ModelForm组件渲染  list、增、删、改页面
    def get_modelform_class(self):
        """ModelForm组件"""
        if not self.modelform_class:
            from django.forms import ModelForm
            class ModelFormDemo(ModelForm):
                class Meta:
                    model = self.model
                    fields = "__all__"
            return ModelFormDemo
        else:
            return self.modelform_class

    def new_list_play(self):
        """构建 ['checkbox','pk', 'name', 'age', edit,'delete']"""
        temp = []
        temp.append(ModelStark.checkbox)
        temp.extend(self.list_display)
        if not self.list_display_links:
            temp.append(ModelStark.edit)
        temp.append(ModelStark.deletes)
        return temp

    def list_view(self, request):
        print(self.model)  # <class 'app01.models.Book'>  用户访问的模型表

        # 构建表头
        header_list = []  # # header_list = ['选择','pk',...'操作','操作']
        for field in self.new_list_play():
            if callable(field):
                # header_list.append(field.__name__)
                val = field(self,header=True)
                header_list.append(val)
            else:
                if field == "__str__":
                    header_list.append(self.model._meta.model_name.upper())
                else:
                    val = self.model._meta.get_field(field).verbose_name    # 中文名称
                    header_list.append(val)

        # 构建表单
        data_list = self.model.objects.all()        # [obj1,obj2,...]
        new_data_list = []
        for obj in data_list:                   # Book表模型,Author表模型
            temp = []
            for field in self.new_list_play():     # ['name','age']
                if callable(field):                 # edit()  可调用的
                    val = field(self,obj)           # 直接调用edit()函数
                    print('val--------->',val)
                else:
                    val = getattr(obj,field)       # 反射  obj是实例对象,name是方法

                    # list_display_links 按钮
                    if field in self.list_display_links:
                        model_name = self.model._meta.model_name
                        app_label = self.model._meta.app_label
                        _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,))
                        # print(_url)
                        val = mark_safe("<a href='%s'>%s</a>"%(_url,field))

                temp.append(val)

            new_data_list.append(temp)

        print('new_data_list',new_data_list)        # 构造数据  [['jack', 44], ['mark', 33]]

        # 构建一个addurl
        add_url = self.get_add_url()
        return render(request,'list_view.html', locals())

    def add_view(self, request):
        ModelFormDemo=self.get_modelform_class()
        form = ModelFormDemo()
        if request.method == "POST":
            form = ModelFormDemo(request.POST)
            if form.is_valid():
                form.save()
                return redirect(self.get_list_url())

        return render(request, "add_view.html",locals())

    def delete_view(self, request, id):
        url = self.get_list_url()
        if request.method == "POST":
            self.model.objects.filter(pk=id).delete()
            return redirect(url)
        return render(request, "delete_view.html", locals())

    def change_view(self, request, id):
        edit_obj = self.model.objects.filter(pk=id).first()

        ModelFormDemo=self.get_modelform_class()
        form = ModelFormDemo(instance=edit_obj)
        if request.method == "POST":
            form = ModelFormDemo(request.POST,instance=edit_obj)
            if form.is_valid():
                form.save()
                return redirect(self.get_list_url())

        return render(request, "change_view.html",locals())


    def get_urls2(self):
        """构造 add/delete/change"""
        model_name = self.model._meta.model_name
        app_label = self.model._meta.app_label

        temp = []
        temp.append(url(r'^$', self.list_view, name='%s_%s_list'%(app_label,model_name)))
        temp.append(url(r'^add/', self.add_view, name='%s_%s_add'%(app_label,model_name)))
        temp.append(url(r'^(d+)/delete/', self.delete_view, name='%s_%s_delete'%(app_label,model_name)))
        temp.append(url(r'^(d+)/change/', self.change_view, name='%s_%s_change'%(app_label,model_name)))

        return temp

    @property
    def urls2(self):

        return self.get_urls2(), None, None


class StarkSite(object):
    """site单例类"""
    def __init__(self):
        self._registry = {}

    def register(self,model, stark_class=None):
        """注册"""
        if not stark_class:
            stark_class = ModelStark

        self._registry[model] = stark_class(model,self)

    def get_urls(self):
        """构造一层urls app01/book"""
        temp = []
        for model, stark_class_obj in self._registry.items():
            print(model, 'stark_clas_obj', stark_class_obj)  # 不同的model模型表
            """
             <class 'app01.models.UserInfo'> ----> <app01.starkadmin.UserConfig object at 0x00000072DDB65198>
             <class 'app01.models.Book'> ----> <stark.service.stark.ModelStark object at 0x00000072DDB65240>
             """

            app_label = model._meta.app_label     # app01
            model_name = model._meta.model_name   # book
            # temp.append(url(r'^%s/%s'%(app_label, model_name),([],None,None)))
            temp.append(url(r'^%s/%s/'%(app_label, model_name),stark_class_obj.urls2))
            """
               path('app01/userinfo/',UserConfig(Userinfo,site).urls2),
               path('app01/book/',ModelStark(Book,site).urls2),
            """


        return temp

    @property
    def urls(self):

        # return [],None,None
        return self.get_urls(),None,None

site = StarkSite()   # 单例对象

4、app01下的starkadmin.py

from stark.service import stark
from .models import *
from django.forms import ModelForm

class BookModelForm(ModelForm):
    class Meta:
        model = Book
        fields = "__all__"

        labels = {
            "authors":"作者",
            "publishDate":"出版日期",
        }

class BookConfig(stark.ModelStark):
    list_display = ['nid', 'title', 'price']
    modelform_class = BookModelForm


class AuthorConfig(stark.ModelStark):
    list_display = ['nid', 'name', 'age']
    list_display_links = ['name','age']



stark.site.register(Book,BookConfig)
stark.site.register(Publish)
stark.site.register(Author,AuthorConfig)
stark.site.register(AuthorDetail)

print(stark.site._registry)

"""
{<class 'app01.models.Book'>: <stark.service.stark.ModelStark object at 0x0000003AA7439630>,
<class 'app01.models.Publish'>: <stark.service.stark.ModelStark object at 0x0000003AA7439668>,
<class 'app01.models.Author'>: <stark.service.stark.ModelStark object at 0x0000003AA74396A0>,
<class 'app01.models.AuthorDetail'>: <stark.service.stark.ModelStark object at 0x0000003AA7439940>}
"""
原文地址:https://www.cnblogs.com/venicid/p/9495623.html