web/ __init__.py models.py tests.py views.py2. 最简单的web应用 views.py
# coding=utf-8
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
import datetime
def curr_datetime(request):
now = datetime.datetime.now()
html = "<html><body>现在时间是:%s</body></html>" % now
return HttpResponse(html)
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from web.views import curr_datetime
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^time/', curr_datetime),
]
在IDE中run ,访问http://127.0.0.1:8000/time/ 即可看到结果
注意:views.py中的 # coding=utf-8 必须放在第一行!否则出现编码错误。
3.数据库设置及连接
使用pymysql作为mysql的连接驱动 https://github.com/PyMySQL/PyMySQL 有安装说明
命令行 $ pip install PyMySQL 即可
在 settings.py中配置数据库属性
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'shop',
'USER': 'app',
'PASSWORD': 'app',
'HOST': '127.0.0.1',
'PORT': '3306',
'CHARSET': 'utf-8',
}
}
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'web',
)
最关键的一点,在project(shop)的__init__.py文件中,我们添加如下代码:
import pymysql
pymysql.install_as_MySQLdb()
在命令行执行 python manage.py syncdb
如果没有生效 执行 python manage.py makemigrations 之后再执行 python manage.py syncdb 应该就ok了
注意:如果实体发生了变化,比如增删了字段,这是后重新运行不起作用,没有Hibernate舒服
# python manage.py syncdb
# python manage.py makemigrations 之后可能会提示让输入一个默认值,也可以在models.py中的相关字段设置默认值比如cate = models.CharField(max_length=10, default="001")
# python manage.py syncdb
应该就把数据库表的结构更新了
4.Django的单元测试例子
tests.py
# coding=utf-8
from django.test import TestCase
from web.models import Item
# Create your tests here.
class ViewTest(TestCase):
def test(self):
response = self.client.get('/time/')
# self.failUnlessEqual('abc', response.content)
self.assertNotEqual('abc', response.content)
print("测试结果为 %s" % response.content)
class ModelTest(TestCase):
def testItemCrud(self):
# 测试新增数据
item = Item(first_name='肥皂', last_name='大肥皂')
item.save()
print("新增一条Item数据ID:%d" % item.id)
# 测试更新数据
item1 = Item.objects.get(id='%d' % item.id)
item1.last_name = '修改后的肥皂'
item1.save()
item2 = Item.objects.get(id='%d' % item.id)
self.assertEqual('修改后的肥皂', item2.last_name)
Item.objects.create(last_name='手机', first_name='手机', cate='002')
self.assertEqual(2, Item.objects.all().__len__())
item.delete()
self.assertEqual(1, Item.objects.all().__len__())
右键(注意右键的位置,可以单个执行测试,也可以全部执行)Run 'Test:web.test.Views' 跟踪结果即可
4. 登录
urls.py配置:
from django.conf.urls import include, url
from django.contrib import admin
import web.views
urlpatterns = [
url(r'^admin/$', include(admin.site.urls)),
url(r'^time/$', web.views.curr_datetime),
# 系统的欢迎页就是login.html,此处必须有views定义,暂时不清楚如何直接定义htmlurl('^$', web.views.login_page),
# 登录成功之后的index.html页面url('^index_page$', web.views.index_page, name="index_page"),
url('^login_page$', web.views.login_page, name="login_page"),
#处理登录请求的viewsurl(r'^user_login$', web.views.user_login, name="user_login"),
]
views.py
from django.shortcuts import render_to_response from django.http import HttpResponse from django.template import loader, Context from django.template.context_processors import csrf from django.contrib import messages import logging from web.models import User, Item #login登录的处理定义def user_login(request):
logger = logging.getLogger(__name__)
if request.method == 'POST': # 如果表单被提交
logger.debug("=====用户登陆===POST方式=====")
username = request.POST['username']
password = request.POST['password']
elif request.method == 'GET':
username = request.GET['username']
password = request.GET['password']
logger.debug("===用户登陆开始====username:%s==password:=" % username)
# 判定用户和密码正确性
u = User.objects.filter(username=username,password=password)
if u is None:
logger.info("用户名:/s 登陆失败,返回登陆页")
template = loader.get_template('html/login.html')
c = Context({'loginStatus': '失败'})
messages.error(request, "失败!")
return template.render(c)
else:
# template = loader.get_template('html/index.html')
# return HttpResponse(template.render(c))
c = Context({'loginStatus': '成功'})
messages.success(request, "登陆成功,欢迎您!")
return render_to_response('html/index.html', c)
涉及到几个方面的内容:
从页面获取参数 Django1.9开始全部使用request.POST['username']或request.GET['username']方式来获取向template页面传递提示信息messages方式:messages.error(request, "失败!")context方式:c = Context({'loginStatus': '失败'}) template.render(c)数据的读取 u = User.objects.filter(username=username,password=password) 从User表中根据username和password查询判断是否为空 if u is None:日志的使用 logger.debug("===用户登陆开始====username:%s==password:=" % username)
login.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>登录</title> </head> <body> <form action="{% url 'user_login' %}" method="post"> {% csrf_token %} <input type="input" name="username" value="1"/> <input type="text" name = "password" value="2"/> <input type="submit" value="登录" /> </form> {% if messages %} <ul class="messages"> {% for message in messages %} <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> {% endfor %} </ul> {% endif %} </body> </html>
index.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<a href="{% url 'login_page' %}" />login_page</a><br/>
<a href="{% url 'user_login' %}?username=1&password=2" />login</a><br/>
提示信息:{{ loginStatus }}
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
</body>
</html>
5. 经典的CRUD
models.py
class Item(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
cate = models.CharField(max_length=10, default="001")
urls.py
url(r'^item/(?P<func>\b\w{4,30}\b)/$', web.views.item_curd, name="item_curd"),
没有用django内建的机制,只是按自己的方法写了一个demo
url 主要是按“/item/方法名/” 来跳转
views.py
def item_curd(request, func):
# 创建准备
if func == 'preCreate':
item = Item
item.first_name = "item"
item.cate = "001"
c = Context({'item': item})
c.update(csrf(request))
return render_to_response("html/item/create.html", c)
# 创建
if func == 'create':
first_name = request.POST['item.first_name']
last_name = request.POST['item.last_name']
cate = request.POST['item.cate']
item = Item(first_name=first_name, last_name=last_name, cate=cate)
try:
item.save()
messages.success(request, "创建成功")
return redirect("/item/list/")
except RuntimeError:
c = Context({'item': item})
messages.error(request, "创建失败")
return render_to_response("html/item/create.html", c)
# 列表
if func == 'list':
item_list = Item.objects.all()
template = loader.get_template('html/item/browse.html')
context = RequestContext(request, {
'item_list': item_list,
})
return HttpResponse(template.render(context))
# 编辑
if func == 'edit':
id = request.GET['id']
item = Item.objects.get(pk=id)
c = Context({'item': item})
c.update(csrf(request))
return render_to_response("html/item/edit.html", c)
# 保存
if func == 'save':
first_name = request.POST['item.first_name']
last_name = request.POST['item.last_name']
cate = request.POST['item.cate']
item = Item(first_name=first_name, last_name=last_name, cate=cate)
try:
item.save()
messages.success(request, "保存成功")
return redirect("/item/list/")
except RuntimeError:
c = Context({'item': item})
messages.error(request, "保存失败")
return render_to_response("html/item/create.html", c)
browse.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
{% if item_list %}
<ul>
{% for item in item_list %}
<li><a href="/item/edit/?id={{ item.id }}">{{ item.first_name }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No item are available.</p>
{% endif %}
</body>
</html>
edit.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>edit</title>
</head>
<body>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>创建Item</title>
</head>
<body>
<form action="{% url 'item_curd' 'save' %}" method="POST">
{% csrf_token %}
first_name:<input name="item.first_name" type="text" value="{{ item.first_name }}" /><br/>
last_name:<input name="item.last_name" type="text" value="{{ item.last_name }}" /><br/>
cate:<input name="item.cate" type="text" value="{{ item.cate }}" /><br/>
<input name="submit" type="submit" value="保存" />
</form>
</body>
</html>
</body>
</html>