【Django】Web应用开发经由
【Django开发经由】
本来以为看完网上的入门教程之后就可以看书详细学习一下,没想到手头上的这本书也讲得不是太详细。。无奈,不过好在这本书从无到有建立一个网站的流程还算可以,就以这个角度简单记录一下,顺便也对之前发现但是还没来得及记录的一些东西进行一些总结。
■ 建立项目
首先是建立项目,我没用django-admin的命令行,而是直接用了Pycharm的建立新项目。建立完成之后就有了项目结构,关于自动创建的几个文件分别是哪些作用。可以特别提一下的是urls.py文件在理想情况下应该是到各个模块的路由(也就是说除了默认的^admin/之外尽量不直接路由到一个界面而是一个Django下的App,让App进一步规定url到响应函数的映射)。另外wsgi.py这个文件一般不用动。
因为djangosite/urls.py中的路由只是路由到模块这一层,所以我们肯定要startapp几个App来充实内容。比如我们创建一个test。此时会提示创建失败,因为在创建App目录的时候里面有一个test.py的文件,如果App也叫test的话就会引起模块名的混乱了。所有App名字就改成mytest吧。
■ 基础路由与视图设置
基础的路由设置就不多说了,这里讲一下之前没有提到过的几个路由设置的技巧:
● 多层URI的路由
之前说到过的所有路由设置全部都是基于一个不变的如url(r'^test/'),但是作为一个正则表达式很明显有更加灵活的用法。比如下面这样的用法:
###djangosite/urls.py###
urlpatterns = [
url(r'^test/', include('mytest.urls')), #新增这行
] ###mytest/urls.py###
from django.conf.urls import url
import views urlpatterns = [
url(r'^add/(\d+)/(\d+)/', views.add)
] ###mytest/views.py###
from django.http import HttpResponse
def add(request,a,b):
a = int(a)
b = int(b)
return HttpResponse('<p>%s</p>' % (a + b) )
如此,在访问如test/add/3/4的时候就可以看到返回的是7了。其要点在于,把路由表示的正则表达式中的子模式自动提取出来并作为参数传递给响应函数。需要注意参数个数应该和子模式个数一致。
● 静态文件
一个网站的javascript,css,图片等这些内容一般都作为静态文件放在服务器上。
相比于flask默认把项目根目录的一个static子目录作为静态文件的存放位置,并且把URI/static/直接和其相关起来相比,Django在默认情况下是没有配置静态文件的目录的。如果需要在项目根目录中像flask一样有个静态文件存放的地方的话那么可以这么干:
首先当然是在根目录下面创建static文件夹,里面可以放上一些文件。
###djangosite/settings.py###
STATIC_URL = '/static/' #这条是默认有的,但是光有这条是不行的
STATICFILES_DIRS = (BASE_DIR,'static') #新加,注意没有os.path.join
设置完静态文件的存放之后还可以通过如下的方式进行和前端的互动,也就是说前端可以直接引用一些静态文件,这正是我们的目的:
{% load staticfiles %}
<script type="text/javascript" src="{% static 'path/to/file' %}">
■ 关联数据库
之前的文章中提到过关联数据库的几个步骤。首先是修改settings.py中的DATABASES配置项,然后在相关的App下的models.py文件,修改之创建模型。看到书上之后知道了,python manage.py makemigrations的时候可以在后面加上一个App名,表示只固化这个App相关的模型的变动。
但是直接python manage.py mytest的话会报错说没有安装APP,确实我们还需要到settings.py里面去设置一下INSTALLED_APPS这个配置。之前在文章中说的是直接以App的名字去INSTALL,不过这里介绍一种看起来更加时髦的办法,在每个新建的APP下面会自动有一个apps.py的文件,里面默认生成了一个XxxxConfig的类,继承自django.apps.AppConfig类。可以把这个类给写到INSTALLED_APPS里面去,目前来看效果是一样的。这是因为这个AppConfig类中有类似name,module,path,label等和一个App(老打App好麻烦,之后我们都称App为模块好了)相关的信息。所以直接在INSTALLED_APPS里面写模块名和写这个类效果一样,我怀疑即使是写模块名可能也是根据这个模块名来找这个类然后加载。
然后就是熟悉的python manage.py makemigrations mytest,然后再python manage.py migrate。这里还注意到了一点,在第一次初始化数据库时,进行makemigrations之后,数据库中首先生成了一张django_migrations的表,然后migrate之后才有了其他乱七八糟的那些表的。
■ 表单视图
下面明确一下如何方便地把一个数据库模型类变成一个表单类:
###mytest/models.py###
from django.db import models class Moment(models.Model):
content = models.Charfield(max_length=200)
user_name = models.Charfield(max_length=20)
kind = models.Charfield(max_length=20)
def __unicode__(self):
return self.user_name,self.content ###mytest/views.py###
from django.forms import ModelForm
from mytest.models import Moment class MomentForm(Form):
class Meta: #采用了子类的方式进行类的转换
model = Moment
fields = '__all__' #__all__是指把模型类中的所有字段都导入表单类中
fields也可以写类似('content','user_name','kind')这样的。
● 更高级一点的模型类
插入在这里有些唐突,不过我们可以这样改造一下models.py中的类以使表结构(不涉及表之间的结构)更加复杂。
KIND_CHOICES = (
('Python技术','Python技术'),
('数据库技术','数据库技术'),
('经济学','经济学'),
('文体咨询','文体咨询'),
('个人心情','个人心情'),
('其他','其他')
) class Moment(models.Model):
content = models.Charfield(max_length=200)
user_name = models.Charfield(max_length=20,default='无名氏')
kind = models.Charfield(max_length=20,choices=KIND_CHOICES,default=KIND_CHOICES[0])
这个类的kind字段已经有了一些合法的值的选项,实际上这个kind字段在表单中就会成为一个SelectField了,虽然在数据库中还是varchar类型的。
然后就是编写模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>消息录入页面</title>
</head>
<body>
<form action="?" method="post">
<fieldset>
<legend>请输入并提交</legend>
{{ form.as_p }}
<input type="submit" value="submit" />
</fieldset>
</form>
</body>
</html>
再编写views中的响应函数:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render
from mytest.forms import MomentForm def moments_input(request):
if request.method == 'POST':
form = MomentForm(request.POST)
if form.is_valid():
moment = form.save()
moment.save()
return HttpResponseRedirect(reverse('static_test_name'))
else:
form = MomentForm() return render(request,'moments_input.html',{'form':form})
这段代码又有点新鲜的东西,HttpResponseRedirect顾名思义和django.shortcuts.redirect是差不多的,起到一个重定向的作用。reverse函数就像flask里的url_for,可以把一个endpoint形式的响应函数转化成相应的url,和url_for一样reverse也有一个args参数(或kwargs参数),可以给生成出来的GET请求的url自动加上参数。
嗯。。书上的是endpoint形式的,可是我自己试了下发现并不行只有像上面代码写得那样才能成功得到url并进行重定向。那么static_test_name是什么?其实是在mytest/urls.py中设置url路由的时候,原先是url(r'^statictest',views.static_test)改成了url(r'^statictest',views.static_test,name='static_test_name')。只有设置了name参数,然后在reverse中参数写成这个name才可以顺利得到url。
save什么的就是存进数据库,其实据我估计这边两个save是多余的,只要form.save()即可。我把下面的注释掉也能把数据顺利存进数据库。
嗯。。管理界面上篇文章讲的挺详细了,就不多说了。
【Django】Web应用开发经由的更多相关文章
- Django Web接口开发
什么是接口 接口一般来讲分为两种: (1)程序内部的接口:方法与方法.模块与模块之间的交互,程序内部抛出的接口,如登录发帖,发帖就必须要登录,如果不登录不能发帖,发帖和登录这两个模块之间就要有交互,就 ...
- Django web框架开发基础-django实现留言板功能
1.创建项目 cmd django-admin startpoject cloudms 2.创建APP cmd django-admin startapp msgapp 3.修改settings,T ...
- 03 Django web服务开发 - URL路由
Django中的APP -Django中的一个APP就是一个应用的意思 -项目可以包含多个APP(多个应用) -一个项目对应一个网站(生活服务网站) 一个APP队形网站的一个应用(二手交易,家政服务) ...
- 关于《Web接口开发与自动化测试--基于Python语言》
关于封面logo 首先,你会被书封上面logo吸引,这么炫酷?双蛇杖?嗯,这是Requests的新logo. 旧的logo是一只乌龟. 新logo是双蛇杖: 看到新logo我首先想到的是 火爆全网页游 ...
- Django web 开发指南 no such table:
在学习django web开发指南时,发布新博客点击save后会有error提示:no such table balabalabala... 百度了一下说重新运行manage.py syncdb 就可 ...
- web框架开发-Django简介
MVC与MTV模型 MVC Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起,模型负责业务 ...
- Django Web开发学习笔记(1)
一.Python的标准类型 (1)bool型 >>> bool("") False >>> bool(None) False >>& ...
- 第六模块:WEB框架开发 第1章·Django框架开发1~50
01-Django基础介绍 02-Web应用程序1 03-Web应用程序2 04-http请求协议1 05-http请求协议2 06-http协议之响应协议 07-wsgire模块1 08-wsgir ...
- Django Web开发指南笔记
Django Web开发指南笔记 语句VS表达式 python代码由表达式和语句组成,由解释器负责执行. 主要区别:表达式是一个值,它的结果一定是一个python对象:如:12,1+2,int('12 ...
随机推荐
- R语言︱XGBoost极端梯度上升以及forecastxgb(预测)+xgboost(回归)双案例解读
XGBoost不仅仅可以用来做分类还可以做时间序列方面的预测,而且已经有人做的很好,可以见最后的案例. 应用一:XGBoost用来做预测 ------------------------------- ...
- final、finally和finalize的区别
final.finally和finalize的区别 这三者的区别可以从两个方面来说 1.意思解释方面 (1)final是修饰符(关键字) (2)finally是异常处理中的程序块 (3)finaliz ...
- Oracle SQL Developer中SQL语句格式化快捷键
Oracle SQL Developer中SQL语句格式化快捷键 格式化SQL语句:Ctrl+F7
- free 或delete后指针怎么样了
free()和delete()只是把指针所指向的内存释放掉,但是并没有把指针本身删除,也没有把指针置为NULL; #include<iostream> using namespace st ...
- JavaScript获取select下拉框中的第一个值
JavaScript获取select下拉框中的第一个值 1.说明 获取select下拉框中的第一个值 2.实现源码 <!DOCTYPE html PUBLIC "-//W3C//DTD ...
- vxWorks应用程序加载的另一种办法
现在我们的工作中,应用程序一般都是和BSP联编,然后将vxworks_rom.bin烧到班子里.在BSP启动后,调用应用程序的函数的. 但是这样有个问题,就是应用程序和BSP结合的太紧密了.BSP开发 ...
- Java中的java.math.BigInteger
Java中的java.math.BigInteger /** * */ package com.you.model; /** * @author YouHaidong * */ public clas ...
- 机器学习相关的tutorial
1. MRF 马尔可夫随机场 http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/AV0809/ORCHARD/ 从MRF,讲到Gibbs分 ...
- .Net之路,感谢对我深远影响的三位前辈
为什么要写这篇文章?为什么创立这个站点? 本人大四,学习.Net三年有余,随着近期开始转向对.Net Core的关注,我开始了解到了张善友(www.csharpkit.com).腾飞(www.jess ...
- 消息队列mq的原理及实现方法
消息队列技术是分布式应用间交换信息的一种技术.消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走.通过消息队列,应用程序可独立地执行--它们不需要知道彼此的位置.或在继续执行前不需要等待 ...