Django框架(六)---- app部件协作

Django框架(六)---- app部件协作


 

该实例

基于:Python3.6,Django-1.11,MySQL-5.7,(Windows)

实现:访问Django服务,进行数据库信息的增删改功能


前奏:1、创建Django项目:django-admin startproject demo

   2、创建app:python manage.py startapp mytest (manage.py文件一级的目录下)

   3、创建templates目录 (manage.py文件一级的目录下),在templates目录下,创建mytest目录

   4、于settings.py文件内设置:(1) 于INSTALLED_APPS中添加mytest

                  (2)TEMPLATES中的DIRS添加:os.path.join(BASE_DIR, 'templates')

                  (3) DATABASE中,删除默认sqlite3设置,添加mysql设置

   5、复制一份demo/urls.py到mytest中

   6、在demo/__init__.py文件中添加代码:import pymysql

                         pymysql.install_as_MySQLdb()

   7、于demo/urls.py文件中的urlpatterns中添加:url(r'^mytest/', include('mytest.urls'))

   8、创建空的数据库,数据库名根据第四步中的DATABASE

   9、创建数据库表,建表语句:

      


主菜:

1、根据之前创建的数据库表,在models.py中创建model类,其中的三个属性和数据库表的字段的数据类型保持一致:

1 class Users(models.Model):
2     name = models.CharField(max_length=32)
3     age = models.IntegerField(default=20)
4     phone = models.CharField(max_length=16)

2、在views.py视图文件中,创建所需要的视图函数,先起个名字,pass:

 1 from .models import Users
 2 
 3 def user(request): # 展示数据表中的数据
 4     pass
 5 
 6 def adduser(request): # 预备跳转到添加数据的模板Html
 7     pass
 8 
 9 def insertuser(request): # 将add.html模板传来的数据添加进入数据库表
10     pass
11 
12 def deluser(request): # 删除数据
13     pass
14 
15 def edituser(request): # 跳转到edit.html模板,修改
16     pass
17 
18 def updateuser(request): # 将edit.html模板传来的修改过的数据进行数据库表更新
19     pass

3、在mytest/urls.py子路由文件中,设置其中每个功能规定的url规则,以及指向对应的视图:

 1 from django.conf.urls import url
 2 
 3 from . import views
 4 
 5 app_name = 'mytest'
 6 urlpatterns = [
 7     url(r'^$', views.user, name='user'),    # 展示
 8     url(r'^user/add$', views.adduser, name='user_add'),  # 添加
 9     url(r'^user/insert$', views.insertuser, name='user_insert'),  # 提交添加
10     url(r'^user/del/(?P<userid>[0-9]+)$', views.deluser, name='user_del'),  # 删除
11     url(r'^user/edit/(?P<userid>[0-9]+)$', views.edituser, name='user_edit'),  # 修改
12     url(r'^user/update$', views.updateuser, name='user_update'),  # 提交修改
13 ]

  解析:1、app_name:本例中实际只有一个应用程序mytest,实际开发中会有多个app,可以在这里设置app_name进行区分相应的视图

      2、在删除和修改的url()中,正则中有(?P<userid>[0-9]+),?P<userid>代表指定的deluser和edituser除了request参数,还有一个叫做userid的参数

      3、每个url()中,都有一个叫做name的参数,唯一不重复,这些name参数值,会在视图模板中用到,目的是为了项目开发后,修改前面正则匹配规则后,可以作用于项目全局

4、开始进行模板创建以及view函数的构建:

  (1)、现在需要一个模板,模板展示mytest app对应的数据库表中的数据信息:

    首先,先将views.user函数构建完成,实现功能:从数据库表中读取所有数据,并且将数据传送给相对应的user.html模板

1 from django.shortcuts import render
2 from .models import Users
3 
4 def user(request):
5     lists = Users.objects.all()
6     context = {"user_list": lists}
7     return render(request, "mytest/user.html", context)

           分析:上述代码中,需要提前导入models模块中的Users类,用于创建Users.objects这个数据库表映射

           Users.objects.all():表示获取数据库表中的所有数据

           context:为传送给模板的数据,必须是一个字典类型,"user_list"这个key值,会在模板中使用到

             view视图函数必须返回一个HttpResponse,这里没有用到Django.http.HttpResponse,用到了Django提供的快捷方式render()函数

              render()函数接收接收请求对象作为第一个参数,模板名称作为第二个参数,字典作为可选的第三个参数。

    然后创建一个简单的模板user.html在templates/mytest目录下:

 1 <center>
 2         {% include "mytest/menu.html" %}
 3         <table width="500" border="1">
 4             <tr>
 5                 <th>ID</th>
 6                 <th>Name</th>
 7                 <th>Age</th>
 8                 <th>Phone</th>
 9                 <th>edit/del</th>
10             </tr>
11             {% for v in user_list %}
12                 <tr>
13                     <td>{{ v.id }}</td>
14                     <td>{{ v.name }}</td>
15                     <td>{{ v.age }}</td>
16                     <td>{{ v.phone }}</td>
17                     <td>
18                         <a href="{% url 'mytest:user_edit' v.id %}">edit</a> |
19                         <a href="{% url 'mytest:user_del' v.id %}">del</a>
20                     </td>
21                 </tr>
22             {% endfor %}
23         </table>
24     </center>

    这里显示在html的body中的代码:

        解析:可以看到代码实现了一个table标签,里面通过for遍历由上面views.user视图传递过来的user_list,取出其中的四个数据,填充进入tr的td中

           每行预留了修改和删除数据的按钮,这个后续会进行补充修改

           第2行的{% include "mytest/menu.html" %} 后续会讲到

        在数据库表中输入一些数据,运行Django服务,浏览器输入 127.0.0.1:8000/mytest,可以看到数据库表中的数据:

        

  (2)、现在需要填加 向数据库表中添加数据的功能:

     首先,补充完views.add函数,目的是为了在点击按钮后,跳转到add.html模板中:

1 def adduser(request):
2     return render(request, "mytest/add.html")

      然后创建add.html模板,代码为在add.html中的body的内容:

 1 <center>
 2         {% include "mytest/menu.html" %}
 3         <form action="{% url 'mytest:user_insert' %}" method="POST">
 4             {% csrf_token %}
 5             <table width="320">
 6                 <tr>
 7                     <td>Name: </td>
 8                     <td><input type="text" name="name"></td>
 9                 </tr>
10                 <tr>
11                     <td>Age: </td>
12                     <td><input type="text" name="age"></td>
13                 </tr>
14                 <tr>
15                     <td>Phone: </td>
16                     <td><input type="text" name="phone"></td>
17                 </tr>
18                 <tr>
19                     <td colspan="2">
20                         <input type="submit">
21                         <input type="reset">
22                     </td>
23                 </tr>
24             </table>
25         </form>
26     </center>

      这里创建了一个信息输入表,以POST方法,提交其中的数据到子路由中的user_insert所指向的视图中去进行后续处理;

      这里需要注意的是第4行的代码,因为本页的数据是按照POST方式传送的,必须要有一个类似令牌的数据和我们的User数据一同传送过去,否则Django会拒绝你的传送,

        究其原因,是为了数据的安全,由中间件django.middleware.csrf.CsrfViewMiddleware控制,可以在settings.py文件中的中间件设置中找到。

      在第3行的action,它的值表示,将form表单中的数据提交给name="user_insert"的子路由urls.py中的url,因为之前在子路由中标明了app_name="mytest",所以这里使用mytest:user_insert写法

  (3)、上面两个模板中,都带一个 {% include "mytest/menu.html" %}

    在书写模板时,有些功能部件可以单独摘取出来,写成其他的html,之后再需要这个功能的时候,可以导入代码中,避免每个模板都要重写这写部件;

    例如在本例中,我们在页面的上面构建两个按钮,一个是展示所有数据,一个就是添加数据,这两个构建需要贯穿全部模板,那么就可以创建一个menu.html文件

1 <a href="{% url 'mytest:user' %}">show users</a> |
2 <a href="{% url 'mytest:user_add' %}">add user</a>

    然后,在每个模板调用这个menu.html时,使用{% include "   " %}语法在合适的位置导入即可

  

  (4)、在上面的add.html模板中,填写需要添加的User信息,点击提交按钮,会以POST方法将数据传送给name="user_insert"的views.insertuser视图,进行存储到数据库

    首先将views.insert_user函数补充完整

 1 def insertuser(request):
 2     try:
 3         ob = Users()
 4         ob.name = request.POST.get("name", "")
 5         ob.age = request.POST.get("age", 20)
 6         ob.phone = request.POST.get("phone", "")
 7         ob.save()
 8         context = {
 9             "info": "Save OK"
10         }
11     except:
12         context = {
13             "info": "Error"
14         }
15     return render(request, "mytest/info.html", context)

      解析:首先建立一个Users对象,然后进行赋值,因为是以POST方法传送到insetuser函数的,所以需要用request.POST,然后获取POST中的value值,第二个参数代表默认,没有对应值的时候,使用默认值

         这里没有数据库表的id字段值,因为它是自增主键,存储时会自动生成

         想要存储进数据库表,还需要调用save()函数,这条数据才会真正存储到表中

         我们可以创建一个info.html模块,传递保存成功或者错误的文本,当在add.html点击提交时,经过后台操作,反馈是否成功的信息

  

  (5)、在浏览器操作删除表中的数据,就目前数据库表,删除一个元素,需要利用它的id字段值,那么views.deluser视图函数:

1 from django.shortcuts import render, redirect
2 from django.core.urlresolvers import reverse
3 
4 def deluser(request, userid):
5     ob = Users.objects.get(id=userid)
6     ob.delete()
7     return redirect(reverse("mytest:user"))

     在调用deluser函数时,需要传递一个id字段值,之前在子路由中使用了   ?<userid>  ,所以此处的id字段值使用userid作为参数名

     使用get()方法,得到userid对应的这条数据后,使用delete()进行数据库表的数据删除操作

     此时,删除成功后,可以跳转到user.html模板,看到删除一条数据后剩余的数据,

        但是如果使用render(request, "mytest/user.html"),则会产生一个现象,页面显示的是user.html模板内容,但是此时的url显示的是127.0.0.1:8000/mytest/del/...,不对应

        所以此处使用Django的重定向,使得删除数据后,url为 127.0.0.1:8000/mytest

       之前在user.html模板中,预留了文本值为del的a标签的href属性,到这里就可以设置成:{% url 'mytest:user_del' v.id %}

        这里传入一条数据的id值 v.id到del_user视图函数

  (6)、在浏览器修改表中的数据,需要一个edit.html模板

 1 <center>
 2         {% include "mytest/menu.html" %}
 3         <form action="{% url 'mytest:user_update' %}" method="POST">
 4             {% csrf_token %}
 5             <input type="hidden" name="id" value="{{ user.id }}">
 6             <table width="320">
 7                 <tr>
 8                     <td>Name: </td>
 9                     <td><input type="text" name="name" value="{{ user.name }}"></td>
10                 </tr>
11                 <tr>
12                     <td>Age: </td>
13                     <td><input type="text" name="age" value="{{ user.age }}"></td>
14                 </tr>
15                 <tr>
16                     <td>Phone: </td>
17                     <td><input type="text" name="phone" value="{{ user.phone }}"></td>
18                 </tr>
19                 <tr>
20                     <td colspan="2">
21                         <input type="submit">
22                         <input type="reset">
23                     </td>
24                 </tr>
25             </table>
26         </form>
27     </center>

    解析:这个页面依旧使用POST方法传送数据,到views.updateuser视图中进行修改后的数据处理;

       在3个input标签中,分别设置value属性,将原本的数据值显示出来,其中使用了user代表传送过来的数据

       在form表单中,有一条隐藏的input,设置其中的value为原数据的id,这个值无法改动,但是需要这个值和其他三个修改后的值一同传送给views.updateuser视图函数

    现在补充完整views.edituser视图函数:

1 def edituser(request, userid):
2     ob = Users.objects.get(id=userid)
3     if ob is None:
4         return HttpResponse("No find info")
5     context = {"user": ob}
6     return render(request, "mytest/edit.html", context)

     如deluser视图函数一样,需要传入一个id值,将查询到的数据信息,组成一个字典,key值就是在edit.html模板中表示原数据的名称,将查询到的数据信息传送给edit.html模板

  (7)、第6步中,将修改后的数据信息以POST方法传递给views.updateuser视图函数,所以这里需要补齐updateuser():

 1 def updateuser(request):
 2     try:
 3         ob = Users.objects.get(id=request.POST.get("id"))
 4         ob.name = request.POST.get("name")
 5         ob.age = request.POST.get("age")
 6         ob.phone = request.POST.get("phone")
 7         ob.save()
 8         context = {
 9             "info": "Edit OK"
10         }
11     except:
12         context = {
13             "info": "Error"
14         }
15     return render(request, "mytest/info.html", context)

      解析:首先我们根据传送过来的request.POST中的数据id值,首先查找出在数据库表中的对应的数据,然后将request.POST中的name,age,phone分别赋值给这个原数据,并且保存

         最后根据是否成功,跳转到info.html

至此:一个简单的应用,浏览器操作数据库数据交互。一整套下来,可以理解app部件之间的相互关系,数据的传递等等。。

如找出错误,请在下面写留言指正,谢谢~

相关查找,可以使用这个 Django-1.10中文文档来查看

    

猜你喜欢

转载自www.cnblogs.com/lambs/p/9180664.html
今日推荐