stark组件03

优化代码

1:页面的增删改查url反转的封装到类里:ModelSatrk

    # 编辑页面的url
    def get_edit_url(self,obj):
        edit_url = reverse("%s_%s_change" % self.app_model_name,args=(obj.pk,))
        return edit_url
    # 删除页面url
    def get_delete_url(self,obj):
        del_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
        return del_url

    def get_add_url(self,obj):
        add_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
        return add_url

    def get_list_url(self,obj):
        list_url = reverse("%s_%s_delete" % self.app_model_name,args=(obj.pk,))
        return list_url

2:显示页面的编辑和删除按钮

    # 编辑按钮
    def edit(self,obj=None,is_header=False):
        if is_header:
            return "操作"
        return mark_safe("<a href='%s'>编辑</a>"%self.get_edit_url(obj))

    # return 的url需要反向解析,需要取到name的值

    # 删除按钮
    def delete(self,obj=None,is_header=False):
        if is_header:
            return "操作"
        # 如何反向解析url
        return mark_safe("<a href='%s'>删除</a>"%self.get_delete_url(obj))

增删改查页面

# 使用modelform 处理的基本流程    
添加页面:
    get请求:
       form=UserModelForm()------>渲染表单标签
    post请求:
        form=UserModelForm(data=request.POST)
        if form.is_valid():
           form.save()-------->create一条记录
    编辑页面:
    get请求:
        edit_obj=User.objects.filter(pk=id).first()
        form=UserModelForm(instance=edit_obj)------>渲染表单标签
    post请求:
        edit_obj=User.objects.filter(pk=id).first()
        form=UserModelForm(data=request.POST,instance=edit_obj)
        if form.is_valid():
           form.save()-------->对edit_obj的数据更新为request.POST

 

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
<h3>添加数据</h3>

<form action="" method="post" novalidate>
    {% csrf_token %}
     {{ form.as_p }}
    <input type="submit" value="submit">
</form>



</body>
</html>
html

需要后端展示页面传值

add_url=self.get_add_url()

增的页面表单第二种渲染方式

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    <style>
        .form-group .input_style input {
            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>
</head>
<body>
<h3>添加数据</h3>
{# 第一种渲染表单方式 #}
{#<form action="" method="post" novalidate>#}
{#    {% csrf_token %}#}
{#     {{ form.as_p }}#}
{#    <input type="submit" value="submit">#}
{#</form>#}
{# 第三种渲染表单方式 #}
<div class="container">
    <div class="row">
        <div class="col-md-6">
            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for field in form %}
                    <div class="form-group">
                        <label for="">{{ field.label }}</label>
                        <div class="input_style">
                            {{ field }}
                            <span class="error pull-right">{{ field.errors.0 }}</span>
                        </div>
                    </div>
                {% endfor %}

                <p><input type="submit" class="btn btn-default " value="提交"></p>
            </form>

        </div>
    </div>
</div>


</body>
</html>
View Code

关于显示错误信息

1:用户定制了(显示中文的)

2:用户没有定义(显示英文)

需要添加 model_form_class=None 变量来判断当前用户有没有定义信息

from django.utils.safestring import mark_safe
from django.urls import reverse
from django.forms import ModelForm
#
class BookModelForm(ModelForm):
    class Meta:
        model=Book
        fields='__all__'   # 展示字段
        error_messages={        # 针对book表的error_messages
            "title":{"required":"不能为空"},
            "price":{"required":"不能为空"},
        }


class BookConfig(ModelSatrk):
    list_display = ["id","title","price",]  # z这个list_display只针对Book表
    model_form_class=BookModelForm  # 当用户定制显示信息,就自己定制的,没有用默认
# 自制注册功能(admin表的注册

site.register(Book,BookConfig)
stark
    # 添加页面视图
    def add_view(self,request):
        # 基于modelform
        # 先走用户的(如果用户写了这个名字,就用用户的) 如果为空既是用户没有定制显示信息
        if not self.model_form_class:  # 用父类
            ModelFormClass=self.get_modelform_class()
        else:                           # 用户定义了
            ModelFormClass=self.model_form_class

        if request.method=="GET":
            form=ModelFormClass()  # 取到当前表数据(渲染表单表单)
            return render(request,"stark/add_view.html",{"form":form})
        else:
            form=ModelFormClass(data=request.POST)
            if form.is_valid():    # is_valid 判断当前数据通不通过
                form.save()         # 新建一条数据
                return redirect(self.get_list_url())
            else:                   # 数据有问题
                return render(request, "stark/add_view.html", {"form":form})

优化(这部分代码在下面重复调用较多)

        if not self.model_form_class:  # 用父类
            ModelFormClass=self.get_modelform_class()
        else:                           # 用户定义了
            ModelFormClass=self.model_form_class

把他封装到类里面

    # 添加页面视图
    def add_view(self,request):
        # 基于modelform

        ModelFormClass=self.model_form_class
        if request.method=="GET":
            form=ModelFormClass()  # 取到当前表数据(渲染表单表单)
            return render(request,"stark/add_view.html",{"form":form})
        else:
            form=ModelFormClass(data=request.POST)
            if form.is_valid():    # is_valid 判断当前数据通不通过
                form.save()         # 新建一条数据
                return redirect(self.get_list_url())
            else:                   # 数据有问题
                return render(request, "stark/add_view.html", {"form":form})



    # 编辑视图
    def change_view(self,request,id):
        edit_book = self.model.objects.filter(pk=id).first()  # 取到要修改的数据对象
        ModelFormClass = self.model_form_class
        form = ModelFormClass(instance=edit_book)  # 需要编辑的内容
        if request.method=="GET":
            form=ModelFormClass(instance=edit_book)
            return render(request,"stark/change_view.html",{"form":form})
        else:
            form=ModelFormClass(data=request.POST,instance=edit_book)
            if form.is_valid():
                form.save()
                return redirect("/index/")
            return render(request,"stark/change_view.html",{"form":form})
修改的两个视图

优化二:添加页面和编辑页面基本相同 利用

include

相同部分放到一个form.html里面

<div class="container">
    <div class="row">
        <div class="col-md-6">
            <form action="" method="post" novalidate>
                {% csrf_token %}
                {% for field in form %}
                    <div class="form-group">
                        <label for="">{{ field.label }}</label>
                        <div class="input_style">
                            {{ field }}
                            <span class="error pull-right">{{ field.errors.0 }}</span>
                        </div>
                    </div>
                {% endfor %}

                <p><input type="submit" class="btn btn-default " value="提交"></p>
            </form>

        </div>
    </div>
</div>

调用

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    <style>
        .form-group .input_style input {
            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>
</head>
<body>
<h3>添加数据</h3>
{# 第一种渲染表单方式 #}
{#<form action="" method="post" novalidate>#}
{#    {% csrf_token %}#}
{#     {{ form.as_p }}#}
{#    <input type="submit" value="submit">#}
{#</form>#}
{# 第三种渲染表单方式 #}
{% include 'stark/form.html' %}


</body>
</html>
add
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    <style>
        .form-group .input_style input {
            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>
</head>
<body>
<h3>添加数据</h3>
{# 第一种渲染表单方式 #}
{#<form action="" method="post" novalidate>#}
{#    {% csrf_token %}#}
{#     {{ form.as_p }}#}
{#    <input type="submit" value="submit">#}
{#</form>#}
{# 第三种渲染表单方式 #}
{% include 'stark/form.html' %}



</body>
</html>
change

 

需求:将指定字段名变成有链接-----list_display_links

  问题:分为2中情况,1:当有用户定义,用用户的  2、当用户没有定义,就用默认的

#  3 完成注册
from stark.service.site import site,ModelSatrk

from .models import *
from django.utils.safestring import mark_safe
from django.urls import reverse
from django.forms import ModelForm
#
class BookModelForm(ModelForm):
    class Meta:
        model=Book
        fields='__all__'   # 展示字段
        error_messages={        # 针对book表的error_messages
            "title":{"required":"不能为空"},
            "price":{"required":"不能为空"},
        }

# list_display只针对Book表
class BookConfig(ModelSatrk):
    list_display = ["id","title","price",]  # 用户用于页面显示的字段
    model_form_class=BookModelForm          # 当用户定制显示错误信息,就自己定制的,没有用默认
    list_display_links = ["title"]          # 用户用于定制添加跳转编辑页面字段
# 自制注册功能(admin表的注册

site.register(Book,BookConfig)
stark
    # 展示数据
    def show_list_view(self,request):
        print("self.model",self.model)  # 打印当前表
        # 生成表表头
        header_list=[]
        for field in self.get_list_display():                     # ["id","title","price","edit"]
            if callable(field):
                # header_list.append(field.__name__)
                val = field(self,is_header=True)            # 定义了一个is_header=True变量
                header_list.append(val)
            else:
                if field=="__str__":                        # 默认样式
                    header_list.append(self.model._meta.model_name.upper())
                else:
                    field_obj=self.model._meta.get_field(field)
                    header_list.append(field_obj.verbose_name)   # verbose_name 显示描述字段

        #  生成表单部分   # header_list:["ID","标题","价格","操作"]
        data_list = self.model.objects.all()            # 去数据库取来的所有数据 对象
        print("self.list_display",self.list_display)    # 用户定义了self.list_display ['id', 'title', 'price']
                                                        # 用户没有定义self.list_display[]
        # 做成下面我们想要的数据格式
        new_data_list=[]  # 渲染页面的数据
        for obj in data_list:                   #  obj:当前每本书的对象
            temp=[]
            # 当用户定义了list_display的情况  利用反射求值
            for field in self.get_list_display():     # ['id', 'title', 'price',delete,edit] ,
                if callable(field):             #  当遇到delete,edit函数
                    val=field(self,obj)         # 执行函数返回的返回值
                else:                           # 'id', 'title', 'price'
                    val=getattr(obj,field)      # 利用反射getattr取值  当用户没定义list_display用“__str__”
                    #  选择指定字段添加a标签跳转到edit页面
                    if field in self.list_display_links:
                        val=mark_safe("<a href='%s'>%s</a>"%(self.get_edit_url(obj),val))

                temp.append(val)                # 当走默认的话,也会把__str__传到val
            new_data_list.append(temp)
        print(new_data_list)                    # [[1, '《看见》---柴静', Decimal('12.00')], [2, '《围城》---钱钟书', Decimal('12.00')]]

    # 添加新的标签:
        # [
        #   [1, '《看见》---柴静', Decimal('12.00'), "<a href='/stark/app01/book/3/change/'>编辑</a>", "<a href='/stark/app01/book/3/delete/'>删除</a>"],
        #  [2, '《围城》---钱钟书', Decimal('12.00'), "<a href='/stark/app01/book/3/change/'>编辑</a>", "<a href='/stark/app01/book/3/delete/'>删除</a>"]
        # ]
    # '''
    #     [
    #             [1,"xxx"],
    #             [2,"xxxxx"],
    #             [3,"xxxxxxx'],
    #       ]
    #     '''
        add_url=self.get_add_url()
        return render(request,"stark/show_list.html",locals())
site

  

  需求2:当用户指定了添加跳转编辑页面的字段时,将不显示操作的编辑

思路:找到哪里显示了编辑按钮

只需要修改下面逻辑

 

需要跳转到让用户选择肯定或取消

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>删除页面</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
</head>
<body>
{# 将要删除的数据取出来 #}
<div>
    <p>{{ del_obj }}</p></div>
<form action="" method="post">
    {% csrf_token %}

    <input type="submit"  class="btn btn-danger" value="确认删除吗?">
    <a href="{{ list_url }}" class="btn btn-info">取消</a>
</form>

</body>
</html>
HTML
    # 删除视图
    def del_view(self,request,id):
        # 先取到要删除的对象、
        del_obj = self.model.objects.filter(pk=id).first()
        if request.method=="GET":
            list_url = self.get_list_url()
            return render(request,"stark/del_view.html",{"del_obj":del_obj , "list_url":list_url})
        else:
            del_obj.delete()   # 将需要删除的对象删除
            return redirect(self.get_list_url())        # 跳转回显示页面

 

接下来需要添加的功能

       查看页面:
              ---
                 分页器
                 search
                 action
                 fliter

 

posted @ 2018-03-15 19:46  小杜要加油  阅读(152)  评论(0编辑  收藏  举报