zoukankan      html  css  js  c++  java
  • Xadmin控件的实现:〇二增、改视图

    我们在前一章里列出了整个Xadmin的框架,在这一章里我们先讲两个视图——增、改。

    因为增和改差不多,内容都是一样的,只不过改的视图多了个id。我们一步步来实现。因为整个框架是基于上一张的那个Xadmin文件,那么这里就主要讲视图函数

    添加数据视图

     添加数据是用了Django的Form控件自动生成的input标签

    默认效果

    先放出来代码,再来分析,这里放的是一部分ConfXadmin类的代码

     1 class ConfXadmin(object):
     2 
     3     modelform_class = None
     4 
     5     def __init__(self,model,site):
     6         self.model = model
     7         self.model_name = self.model._meta.model_name
     8         self.app_name = self.model._meta.app_label
     9     @property
    10     def urls2(self):
    11         return self.get_urls2(),None,None
    12 
    13     def get_urls2(self):
    14         temp = []
    15         #通过name设置反向解析
    16         temp.append(url(r'^$',self.list_view,name='{}_{}_list'.format(self.app_name,self.model_name)))
    17         temp.append(url(r'^add/$',self.add_view,name='{}_{}_add'.format(self.app_name,self.model_name)))
    18         temp.append(url(r'^(d+)/change/$',self.change_view,name='{}_{}_change'.format(self.app_name,self.model_name)))
    19         temp.append(url(r'^(d+)/delete/$',self.delete_view,name='{}_{}_delete'.format(self.app_name,self.model_name)))
    20         return temp
    21 
    22 
    23     def get_list_url(self):
    24         model_name = self.model._meta.model_name
    25         app_label = self.model._meta.app_label
    26 
    27         _url = reverse("%s_%s_list"%(app_label, model_name)) 
    28         return _url
    29 
    30     def get_modelform_class(self):
    31         if not self.modelform_class:
    32             from django.forms import ModelForm
    33 
    34             class ModelFormDemo(ModelForm):
    35                 class Meta:
    36                     model = self.model
    37                     fields = '__all__'
    38             
    39             return ModelFormDemo
    40         else:
    41             return self.modelform_class
    42 
    43     def add_view(self,request):
    44         ModelFormDemo = self.get_modelform_class()
    45 
    46         if request.method == 'POST':
    47             form = ModelFormDemo(request.POST)
    48             if form.is_valid():
    49                 form.save()
    50 
    51             return redirect(self.get_list_url())
    52 
    53 
    54         form = ModelFormDemo()
    55         return render(request,'add.html',locals())      

    可以发现,这里比前面一章里多了几个方法,因为我们在后面的视图中可能会用到一些特定的url,如何获取到这些url就被封装成函数放在类里。

    form组件的实现是从第30行开始的。首先我们声明类过程中先定义了一个变量modelform_class,值是空,是在没用指定要求的form效果时使用的(默认情况)。

    通过第31行的if条件判断,如果单实例对象site里的键值对里的value,也就是配置类里没有自定义的form组件时就自己定义一个form组件类,然后把这个类返回给add视图里,经过实例化生成一个对象,ModelFormDemo,后面的过程就是正常的from组件的使用了。这里的数据校验没有什么特别要注意的敌方,所以没有加钩子什么的,直接用就行了。

    对应的html代码

    由于我们在视图返回的render里直接调用了locas()方法,会把函数内所有的变量传给模板,所以我们只需要关心的就是变量form。

     1 <body>
     2     <h3>添加页面</h3>
     3     <div class="container">
     4         <div class="col-md-8 col-md-offset-4">
     5                 <form action="" method="post">
     6                     {%csrf_token%}
     7                     {%for field in form%}
     8                     <div>
     9                         <label for="">{{field.label}}</label>
    10                     </div>
    11                     {{field}}
    12                     {%endfor%}
    13                     <button class="btn btn-success pull-right">tijiao</button>
    14                 </form>
    15         </div>
    16     </div>
    17 
    18 </body>

    整个过程就是通过一个for循环吧form里的内容迭代出来,没什么要注意的,显示出来的效果很low

     样式太难看,还是可以利用bootstrap的效果来美化一下

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>添加数据</title>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
        <script src="/static/jquery-3.2.1.min.js"></script>
        <link rel="stylesheet" href="/static/css/add.css">
        <!-- <link rel="stylesheet" href="/static/css/add.css"> -->
    </head>

    在head里导入bootstrap的css和jQuery的文件,然后需要自定义一下input标签,把css代码放进了add.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;
    }
    add.css

    出来的效果还稍微好一些,由于这里不让前端占太多篇幅,先不考虑太多,看看大致的效果

     这样就完成了数据的添加视图的大致内容。

    数据修改

    数据的修改和添加时一样的,先看一下代码

     1 def change_view(self,request,id):
     2     ModelFormDemo = self.get_modelform_class()
     3     edit_obj = self.model.objects.filter(pk = id).first()
     4     if request.method == 'POST':
     5         form = ModelFormDemo(request.POST)
     6         if form.is_valid():
     7             form.save()
     8             return redirect(self.get_list_url())
     9 
    10     form = ModelFormDemo(instance=edit_obj)
    11     return render(request,'change.html',locals())

    由于在RUL里包含了需要修改的数据的id,所以视图函数会多一个参数——id,id是通过URL里的正则获取到的。

    整个代码的逻辑和添加的视图差不多,模板是一样的,通过locals方法传递的变量也是form,唯一一点不同的是在视图中通过id索引到需要修改的QuerySet,然后在实例化form对象的时候吧需要修改的对象赋值给form(通过参数instance,第10行里)

    然后剩下的部分就和添加是一样的了

    其实应该先做一个数据展示的视图,然后对每个book对象加上一个a标签,需要修改的时候点击这个标签直接跳转到这个页面。

    上面的图就是直接访问url的效果

    存在的BUG

    整个修改的视图只是讲了一下逻辑过程,但是这里有一个BUG可以留着以后修改一下:

    在实际生产环境,我们要修改对象的时候是通过点击相应的a标签进入修改的页面

    注意上面动图里的URL,就是点击的change前面的4就是要修改Book对象的id。我们需要的是修改,但是上面的视图中是具备增加功能的。在地址栏中直接输入URL,id如果不存在的会直接弹出一个空白的form组件,和add视图一样。可以看一下代码,可以直接走到save()方法就在数据库里新增了一个book对象。这个明显是不利于权限管理的。所以要注意一下,怎么修改以后有机会再讲吧。

  • 相关阅读:
    王者齐聚!Unite 2017 Shanghai 日程讲师全揭晓
    微软在.NET官网上线.NET 架构指南频道
    期待微软平台即服务技术Service Fabric 开源
    Visual Studio 20周年软件趋势随想
    .NET 十五岁,谈谈我眼中的.NET
    API网关Ocelot 使用Polly 处理部分失败问题
    互联网背景下知识半衰期这么短,如何学习?
    CentOS 7 上面安装PowerShell
    搭建consul 集群
    Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制
  • 原文地址:https://www.cnblogs.com/yinsedeyinse/p/13475072.html
Copyright © 2011-2022 走看看