在前一讲中,姜哥带着大家一起建立了我们的商品模型,并且,利用自带的控制台,生成了一条测试数据。
那么,接下来,我们当然是希望能够在页面上,将商品展示出来咯!比如我随便打开京东的一个页面:
这个就是我们希望的商品列表页面,当然我们不需要这么复杂,先实现最简单的功能,就是把商品先放出来,那就开始动手吧。
在Django框架下开发一个页面,需要以下几个步骤:
3、准备一个页面模板,最后将结果输出到这个模板中,并且将最终结果返回给浏览器。
跟着姜哥一步一步做吧:
我们加入一点内容,准备把关于商品的逻辑处理,都放到一个新的叫做products.py
的文件中去,并且,我们希望我们访问http://localhost/products/
时打开商品列表页:
from django.conf.urls import url
from django.contrib import admin
from shop import views
from shop import products #引入一个新的view文件
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^hello/', views.hello_view,name="hello_view"),
url(r'^products/', products.list_view,name="products_list_view"), #加入对商品列表的url拦截
]
shop
目录下,新建一个文件,叫做
products.py
,这个文件名和上一步骤中我们
urls.py
中
import
进来的
products
要保持一致!在这个文件中填入以下内容:
from django.shortcuts import render
from django.http import HttpResponse
from django.template.response import TemplateResponse
from shop.models import Product
def list_view(request):
#建立一个字典对象,类似java中的map对象,用来存放相应的数据,后续要放到模板文件中去
ctx = {}
#通过django的orm模型,从数据库访问数据
product_list = Product.objects.filter(is_publish=True)
#将数据库查询到的数据,放到字典对象中,名称叫做'product_list',后续在模板中可以用这个名称来访问这个对象
ctx['product_list'] = product_list
#调用django的TemplateResponse,将数据加载到模板中的对应位置
return TemplateResponse(request, 'client/product_list.html', ctx)
关于代码的具体含义,已经在上面的注释里写的很清楚了,这里要解释的问题在于django的模板
机制。
在django开发中,模板特别重要,它就是结果输出的一个框架,我们先在模板文件中,将固定不变的内容填好,然后通过这个TemplateResponse
,将ctx
中的内容,填入到我们在模板中标注出来的地方。
这么说,可能有些空洞,让姜哥把模板的代码贴出来,大家应该就明白了。
在Django中,模板文件存放位置,是可以定义的,在settings.py
文件中的TEMPLATE一节:
姜哥标红框的位置,原来是没有的,我们加上一个templates
,这表明我们要把模板放到我们app目录的templates
目录下。
然后我们在shop
目录下,新建一个templates
目录并且,新建一个目录,client
(为了将来开发管理台,区分下目录),再新建一个模板文件,叫做product_list.html
,现在姜哥的工程目录是这个样子的(截图晚了一点点,姜哥已经把product_list.html
的代码输入了):
打开这个文件,输入以下代码:
<html>
<head>
<meta charset="utf-8"/>
head>
<body>
<h1>商品列表h1>
<ul>
{% for product in product_list %}
<li>
<div class="product-info">
<span class="product-name">商品:{{product.name}}span> |
<span class="product-price">价格:{{product.price}}span> |
<span class="product-create-time">发布时间:{{product.create_time}}span>
div>
li>
{% endfor %}
ul>
body>
html>
在这个页面里,姜哥没有用任何样式,只用了最基础的html
标签,关于样式,姜哥后续会讲到,这里先把关注点聚焦到我们的开发流程上来。
在这个模板文件里,我们用到了django的模板语法,{% %}
大括号框起来的,表示这里是django模板代码,一般用在循环体,判断体上,例如文中的for
循环,也可以用在例如:
{% if xxxx %}
your code
{% else %}
your code
{% endif %}
这种类型的判断体上。 在{% %}
大括号中间,我们前面放入ctx
中的变量可以直接使用,比如例子中的product_list
,就是我们在list_view
中的那个ctx['product_list']
。
{% for product in product_list %}
这一行代码中,我们还定义了一个迭代器变量,叫product,表示product_list
中的每一个product
,后续代码中可以直接使用这个变量。
接着,我们使用双括号,类似{{product.name}}
的形式来获取对应的值。具体每一个product
中有哪些属性可以被获取,完全取决于你py
文件中的定义。我们这里获取的,都是在models
中定义的product
的各个字段,你也可以在我们的list_view
函数中给每一个product
添加一些并不在数据库中的属性。
还记得怎么启动程序吗?先打开一个黑屏窗口:
C:\Users\djang>d:
D:\>cd myBallShop
D:\myBallShop>python manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
March 12, 2018 - 12:43:30
Django version 1.10, using settings 'myBallShop.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
好,程序启动了,在浏览器窗口中输入网址:http://localhost:8000/products/
,可以看到我们的商品列表页已经出来咯!
注:这里可能,有些同学会报错utf-8 codec can't decode byte 0xc9 in position xxxxx
,请大家参考后文的解决办法
有了商品了,还记得怎么通过管理台再添加几个商品吗?不记得的同学,请用这个传送门,直达第五篇,姜哥又加了两个商品:
刷新一下我们的商品列表页看看效果吧:
怎么回事?怎么没效果!!!不可能啊!!!确实不可能,姜哥又看了下代码:
#通过django的orm模型,从数据库访问数据
product_list = Product.objects.filter(is_publish=True)
原来,我们把是否上架,作为了删选条件,而刚才姜哥一激动,添加商品的时候,忘记把商品上架了!
把这个上架的勾子勾上,保存之后,再刷新看看:
哟西!不过,这个发布时间,看上去怪怪的,能不能格式化一下呢?非常简单,我们可以用django的模板过滤器语法来做打开product_list.html
文件,找到发布时间这一行,改成这样:
<span class="product-create-time">发布时间:{{product.create_time|date:"Y-m-d H:i:s" }}span>
我们再create_time后面,加了日期格式化过滤器,django有哪些过滤器可以用,大家可以参考姜哥的这篇文章。再刷新下~
爽了很多~
OK~无论如何,我们今天已经开发了一个商品列表页面了,把我们数据库中的内容展示出来的,虽然这个例子很简单,但是也让我们看到了django的整个开发流程,熟悉了模板机制和部分模板语法。但是,这个页面还非常丑陋,明天姜哥将继续带着大家把这个页面美化起来,看看再django框架下,如何引入样式、js等静态资源。
附:
utf-8 codec can't decode byte 0xc9 in position xxxxx
解决办法
这个问题一般是由于我们py
文件、模板
文件中含有非西文字符,而我们的文件格式又不是utf-8
引起的,一般情况下,请大家这样做:
1、首先尝试删除文件中所有的非英文字符,改用英文试试,一般都可以解决;
2、在notepad++中转换文件所用的编码格式,转换以后,中文可能要重新输入一遍:
3、在每个py
文件的头上,加上# coding=utf-8
经过这个组合拳,大部分问题,都迎刃而解~如果还解决不了,欢迎加姜哥的微信探讨噢~
——————
姜哥的邮箱: [email protected]
姜哥的微信:
——————