Django

·   Django流程

·   Django url

·   Django view

·   Django form

①:Django流程介绍

MTV模式

  注明的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起.

  模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器(C)接受用户的输入调用模型和视图完成用户的请求.

注: 什么是松耦合:简单的说,松耦合是一个 重要的保证互换性的软件开发方法.

Django的MTV模式本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同,Django的MTV分别代表:

Model(模型):负责业务对象与数据库的对象(ORM)

Template(模版):负责如何把页面展示给用户

View(视图):负责业务逻辑,并在适当的时候调用Model和Template

此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

②:Django URL

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。URL的家在是从配置文件中开始。

参数说明:

  ·   一个正则表达式字符串

  ·   一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串

  ·   可选的要传递给视图函数的默认参数(字典形式)

  ·   一个可选的name参数

下面是一个示例URLconf:

from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

注释:

  ·  To capture a value from the URL, just put parenthesis around it.

   (从URL中捕获值,只是把它周围的括号。)

  • There’s no need to add a leading slash, because every URL has that. For example, it’s ^articles, not ^/articles.

   (没有必要添加一个领先的削减,因为每个URL。例如,它的^的文章,而不是^ /文章。)

  · The 'r' in front of each regular expression string is optional but recommended. It tells Python that a string is “raw” – that nothing in the string should be escaped. See Dive Into Python’s explanation.

(每个正则表达式字符串前面的'R'是可选的,但建议。它告诉Python字符串是“原始” - 没有什么字符串中应该进行转义。见深入Python的解释。)

Example requests:

  · A request to /articles/2005/03/ would match the third entry in the list. Django would call the functionviews.month_archive(request, '2005', '03').

(请求/文章/ 2005/03 /匹配列表中的第三项,Django的将调用函数views.monthly存档(要求下,'2005','03')。)

  · /articles/2005/3/ would not match any URL patterns, because the third entry in the list requires two digits for the month.

  (/文章/ 2005/3 /不匹配任何URL模式,因为第三个条目列表中需要两个数字的月. .)

  · /articles/2003/ would match the first pattern in the list, not the second one, because the patterns are tested in order, and the first one is the first test to pass. Feel free to exploit the ordering to insert special cases like this. Here, Django would call the function views.special_case_2003(request)

  (/文章/ 2003 /将匹配第一个模式列表中,没有第二个,因为模式是为了进行测试.第一个是第一个测试通过,随时利用顺序插入这样的特殊情况,这里,Django所说的功能的观点。特殊情况2003(请求))

  · /articles/2003 would not match any of these patterns, because each pattern requires that the URL end with a slash.

  (/文章/ 2003不匹配任何这些模式,因为每个模式要求以斜线结尾的URL。)

  · /articles/2003/03/03/ would match the final pattern. Django would call the functionviews.article_detail(request, '2003', '03', '03').

  (/文章/ 2003/03/03 /将最终的模式相匹配,Django将调用函数views.article细节(的要求,'2003','03','03')。)

Named groups

  · The above example used simple, non-named regular-expression groups (via parenthesis) to capture bits of the URL and pass them as positional arguments to a view. In more advanced usage, it’s possible to use named regular-expression groups to capture URL bits and pass them as keyword arguments to a view.

(上面的例子中使用简单,non-named正则表达式组(通过括号)捕捉到的URL,将他们作为一个视图的位置参数。在更高级的用法,可以使用指定的正则表达式组捕获的URL)

  · In Python regular expressions, the syntax for named regular-expression groups is (?P<name>pattern), where name is the name of the group and pattern is some pattern to match.

(在Python正则表达式,命名正则表达式组的语法是(?P <名>的模式),其中name是组的名称和模式是某种模式相匹配。)

  · Here’s the above example URLconf, rewritten to use named groups:

(下面是上面的例子中的URLconf,改写使用命名组:)

import re

ret=re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/ooo')

print(ret.group())
print(ret.group('id'))
print(ret.group('name'))

正则知识

from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

This accomplishes exactly the same thing as the previous example, with one subtle difference: The captured values are passed to view functions as keyword arguments rather than positional arguments. For example:

(这完成了前面的例子一样,有一个微妙的差异:捕获的值传递给视图函数作为关键字参数而不是位置参数。例如:)  

A request to /articles/2005/03/ would call the function views.month_archive(request, year='2005',month='03'), instead of views.month_archive(request, '2005', '03').

(的请求/用品/ 2005/03/会调用函数views.monthly存档(要求,今年='2005',一个月='03'),而不是views.monthly存档(要求下,'2005','03')。)

A request to /articles/2003/03/03/ would call the function views.article_detail(request, year='2003',month='03', day='03').

(请求/文章/ 2003/03/03 /将调用该函数的观点。文章细节(请求,年= ' 2003 ',月=“03”,天=“03”)。)

In practice, this means your URLconfs are slightly more explicit and less prone to argument-order bugs – and you can reorder the arguments in your views’ function definitions. Of course, these benefits come at the cost of brevity; some developers find the named-group syntax ugly and too verbose.

(在实践中,这意味着你的URLconf稍微更明确,不容易参数顺序错误 - 你可以在你的意见'函数定义重新排序的参数。当然,这些优点来在简短的费用;一些开发商找到命名组的语法丑陋,太冗长。)

常见写法实列:

Captured arguments are always strings:

Each captured argument is sent to the view as a plain Python string, regardless of what sort of match the regular expression makes. For example, in this URLconf line:

(每个捕获的参数发送到视图作为普通的Python字符串,无论什么样的匹配正则表达式做。例如,在该URL配置行:)

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

...the year argument passed to views.year_archive() will be a string,

(…参数传递给视图。年存档()将是一个字符串,)

not an integer, even though the [0-9]{4} will only match integer strings.

(不是整数,即使[0-9]{4}将只匹配整数串。)

Including other URLconfs :

At any point, your urlpatterns can “include” other URLconf modules. This essentially “roots” a set of URLs below other ones.

(在任何时候,您的网址模式可以“包含”其他的URLconf模块。这实质上是“根”的一套低于其他的网址。)

For example, here’s an excerpt of the URLconf for the Django website itself. It includes a number of other URLconfs:

(例如,这里的URL配置为Django的网站本身的摘录。它包括许多其他URL配置的:)

from django.conf.urls import include, url

urlpatterns = [
# ... snip ...
url(r'^community/', include('django_website.aggregator.urls')),
url(r'^contact/', include('django_website.contact.urls')),
# ... snip ...
]

 Passing extra options to view functions:

URLconfs have a hook that lets you pass extra arguments to your view functions, as a Python dictionary.

(URLconf中有一个挂钩,可以传递额外的参数给您的视图功能,作为一个Python字典。)

The django.conf.urls.url() function can take an optional third argument which should be a dictionary of extra keyword arguments to pass to the view function.

(该django.conf.urls.url()函数可以接受这应该是额外的参数的字典传递给视图功能可选的第三个参数。)

For example:

from django.conf.urls import url
from . import views urlpatterns = [
url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

  In this example, for a request to /blog/2005/, Django will call views.year_archive(request, year='2005',foo='bar').

(在本例中,请求/博客/ 2005 / Django将调用视图。年存档(请求,年= ' 2005 ',foo = '参数')。)

This technique is used in the syndication framework to pass metadata and options to views.

(这种技术用于聚合框架通过元数据和视图选项。)

Dealing with conflicts

( 应对冲突)

It’s possible to have a URL pattern which captures named keyword arguments, and also passes arguments with the same names in its dictionary of extra arguments. When this happens, the arguments in the dictionary will be used instead of the arguments captured in the URL.

(可以有一个URL模式捕获关键字参数,并通过参数具有相同名字的字典的额外参数。当这种情况发生时,将使用参数在字典里而不是参数捕获)

需要注意的是,当你加上参数时,对应函数views.index必须加上一个参数,参数名也必须命名为a,如下:

if  auth():

    obj=model.user.filter()

{'obj':obj}

应用

name param

urlpatterns = [
url(r'^index',views.index,name='bieming'),
url(r'^admin/', admin.site.urls),
# url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
# url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
# url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail), ]
################### def index(req):
if req.method=='POST':
username=req.POST.get('username')
password=req.POST.get('password')
if username=='alex' and password=='':
return HttpResponse("登陆成功") return render(req,'index.html') ##################### <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{# <form action="/index/" method="post">#}
<form action="{% url 'bieming' %}" method="post">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit" value="submit">
</form>
</body>
</html> #######################

name的应用

Django views

http请求中产生两个核心对象:

  • http请求:HttpRequest对象

  • http响应:HttpResponse对象
# 获取提交方式
request.method
if request.method == "POST":
times = time.time()
return render(request,'index.html') # 获取前端post提交的数据
request.POST.get('username') # 获取域名后路径
get_full_path()
例:http://127.0.0.1:8000/index33/?name=123 ,req.get_full_path()得到的结果就是/index33/?name=123

HttpRequest对象

def test(request):
# 往前端写入字符串
return HttpResponse("xxx")
# 跳转路径
return redirect('/index/') # 渲染HTML文件两种方式
return render(reuqest, "test.html")
return render_to_response('text.html') # 可以直接将函数中所有的变量传给模板
return render(reuqest, "test.html",locals()) # 可以根据通过字典的方式往前端传值,取值输入key即可
return render(reuqest, "test.html",{'shijie':'你好'})

HttpResponse对象

# path:       请求页面的全路径,不包括域名
#
# method: 请求中使用的HTTP方法的字符串表示。全大写表示。例如
#
# if req.method=="GET":
#
# do_something()
#
# elseif req.method=="POST":
#
# do_something_else()
#
# GET: 包含所有HTTP GET参数的类字典对象
#
# POST: 包含所有HTTP POST参数的类字典对象
#
# 服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
# HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
# if req.POST来判断是否使用了HTTP POST 方法;应该使用 if req.method=="POST"
#
#
#
# COOKIES: 包含所有cookies的标准Python字典对象;keys和values都是字符串。
#
# FILES: 包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中 name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
#
# filename: 上传文件名,用字符串表示
# content_type: 上传文件的Content Type
# content: 上传文件的原始内容
#
#
# user: 是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
# 没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
# 可以通过user的is_authenticated()方法来辨别用户是否登陆:
# if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
# 时该属性才可用
#
# session: 唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。

参数

Django Form

一、基础form提交

比如写一个计算 a和 b 之间的简单应用,网页上这么写.

<!DOCTYPE html>
<html>
<body>
<p>请输入两个数字</p> <form action="/add/" method="POST"><input type="text" name="a"> <input type="text" name="b">
<input type="submit" value="提交">
</form>
</body>
</html>

HTML

把这些代码保存成一个index.html,放在 templates 文件夹中。

网页的值传到服务器是通过 <input> 或 <textarea>标签中的 name 属性来传递的,在服务器端这么接收:

from django.http import HttpResponse
from django.shortcuts import render def index(request):
return render(request, 'index.html') def add(request):
a = request.POST.GET('a')
b = request.POST.GET('b')
a = int(a)
b = int(b)
return HttpResponse(str(a+b)

服务器端

但是,比如用户输入的不是数字,而是字母,就出错了,还有就是提交后再回来已经输入的数据也会没了。

那么,当然如果我们手动将输入之后的数据在 views 中都获取到再传递到网页,这样是可行的,但是很不方便,所以 Django 提供了更简单易用的 forms 来解决验证等这一系列的问题。

二、Django Forms应用

1、简单案例一

在app01下新建一个文件forms.py

from django import forms

class AddForm(forms.Form):
a = forms.IntegerField()
b = forms.IntegerField()

forms.py

(视图函数) views.py 

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.shortcuts import render,HttpResponse
from app01.forms import AddForm def index(request):
if request.method == 'POST':# 当提交表单时
# form 包含提交的数据
form = AddForm(request.POST)
# 如果提交的数据合法
if form.is_valid():
a = form.cleaned_data['a']
b = form.cleaned_data['b']
return HttpResponse(str(int(a) + int(b)))
# 当正常访问时
else:
form = AddForm()
return render(request, 'index.html', {'form': form})

views.py

对应的模板文件 index.html

<form method='post'>
{% csrf_token %}
{{ form }}
<input type="submit" value="提交">
</form>

index.html

这个简单的案例,大家不知道有没有看出其中的蹊跷呢,仔细观察,form类给我做了验证,用户输入错了会弹出报错信息

2丶简单案例二

from django.db import models

# Create your models here.

class BookType(models.Model):
caption = models.CharField(max_length=64) #最大长度 class Book(models.Model):
name = models.CharField(max_length=64) #最大长度
pages = models.IntegerField()
price = models.DecimalField(max_digits=10,decimal_places=2)
pubdate = models.DateField()
book_type = models.ForeignKey('BookType') #当然min_length --最小长度

models.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django.shortcuts import render
from app01.forms import Form1 def form1(request):
if request.method == 'POST':
# 获取请求内容做验证
f = Form1(request.POST)
if f.is_valid():
print(f.cleaned_data)
else:
print(type(f.errors),f.errors)
return render(request,'form1.html',{'error':f.errors,'form':f})
else:
f = Form1()
return render(request,'form1.html',{'form':f})

views.py

在app01下新建一个文件forms.py

#!/usr/bin/env python
# -*- coding:utf-8 -*- from django import forms
from app01 import models class Form1(forms.Form):
# 用户名,给该标签添加一个class属性,还有空值的报错信息修改
user = forms.CharField(
widget=forms.TextInput(attrs={'class': 'c1'}),
error_messages={'required': '用户名不能为空'},) # 密码定义最大长度和最小长度
pwd = forms.CharField(max_length=4,min_length=2)
# 邮箱定义错误信息,required为空值错误信息,invalid为邮箱匹配错误信息
email = forms.EmailField(error_messages={'required': '邮箱不能为空', 'invalid': '邮箱格式错误'})
# 生成多行文本编辑框
memo = forms.CharField(widget=forms.Textarea()) # 下拉菜单实时更新数据库
user_type_choice = models.BookType.objects.values_list('id','caption')
book_type = forms.CharField(widget=forms.widgets.Select(choices=user_type_choice,attrs={'class': "form-control"})) def __init__(self,*args, **kwargs):
super(Form1, self).__init__(*args, **kwargs)
self.fields['book_type'] = forms.CharField(
widget=forms.widgets.Select(choices=models.BookType.objects.values_list('id','caption'),attrs={'class': "form-control"}))

forms.py

HTML页面(form1.html)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.input-group{
position: relative;
padding: 20px;
width: 250px;
}
.input-group input{
width: 200px;
display: inline-block;
}
.input-group span{
display: inline-block;
position: absolute;
height: 12px;
font-size: 8px;
border: 1px solid red;
background-color: darksalmon;
color: white;
top: 41px;
left: 20px;
width: 202px;
}
</style>
</head>
<body> <form action="/form1/" method="post"> <div class="input-group">
{{ form.user }}
{% if error.user.0 %}
<span>{{ error.user.0 }}</span>
{% endif %}
</div>
<div class="input-group">
{{ form.pwd }}
{% if error.pwd.0 %}
<span>{{ error.pwd.0 }}</span>
{% endif %}
</div>
<div class="input-group">
{{ form.email }}
{% if error.email.0 %}
<span>{{ error.email.0 }}</span>
{% endif %}
</div>
<div class="input-group">
{{ form.memo }}
{% if error.memo.0 %}
<span>{{ error.memo.0 }}</span>
{% endif %}
</div>
<div class="input-group">
{{ form.book_type }}
{% if error.book_type.0 %}
<span>{{ error.book_type.0 }}</span>
{% endif %}
</div> <div>
<input type="submit" value="提交">
</div>
</form> </body>
</html>

form1.html

Django|第一部的更多相关文章

  1. Django知识(二)

    上一部链接 django入门全套(第一部) 本章内容 Django model Model 基础配置 django默认支持sqlite,mysql, oracle,postgresql数据库. < ...

  2. 实战Django:官方实例Part1

    [写在前面] 撰写这个实战系列的Django文章,是很久之前就有的想法,问题是手头实例太少,一旦开讲,恐有"无米下锅"之忧. 随着对Django学习的深入,渐渐有了些心得,把这些心 ...

  3. 转一篇:文档笔记之Django QuerySet

    这个放着,说不定以后作一些更深入的查询时,用得着的. http://www.rapospectre.com/blog/7/ 今天刚刚答完辩体完检就跑来更新博客了!!! 先补上第一篇: 一般情况下,我们 ...

  4. django 配置URLconf和获取值

    django中正确配置url匹配找到视图: 1 在项目下的settings.py中ROOT_URLCONF = "项目名.urls" 表示 前台发来请求会先去项目下的test3/u ...

  5. python框架之Django(10)-Form组件

    介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入 ...

  6. 【转】django 与 vue 的完美结合 实现前后端的分离开发之后在整合

    https://blog.csdn.net/guan__ye/article/details/80451318   最近接到一个任务,就是用django后端,前段用vue,做一个普通的简单系统,我就是 ...

  7. Django学习笔记之Django QuerySet的方法

    一般情况下,我们在写Django项目需要操作QuerySet时一些常用的方法已经满足我们日常大多数需求,比如get.filter.exclude.delete神马的感觉就已经无所不能了,但随着项目但业 ...

  8. Django Query

    Making Qeries 一旦创建了数据模型,Django就会自动为您提供一个数据库抽象API,允许您创建.检索.更新和删除对象.本文档解释了如何使用这个API. The models 一个clas ...

  9. python框架django中结合vue进行前后端分离

    一:创建django项目 1.django-admin startproject mysite # 创建mysite项目 2.django-admin startapp app01# 创建app01应 ...

随机推荐

  1. NodeMCU之旅(三):响应配置按钮

    引言 在之前的代码中,要连接的WIFI信息都已写死在代码里,这显然不能适应我们的需求.所以需要想个办法让用户可以配置这些信息. WIFI工作模式 NodeMCU支持STATION,SOFTAP,STA ...

  2. C#的显式接口和隐式接口(转载)

    接口的实现分为:隐式实现和显式实现.如果类或者结构要实现的是单个接口,可以使用隐式实现,如果类或者结构继承了多个接口那么接口中相同名称成员就要显式实现.显示实现是通过使用接口的完全限定名来实现接口成员 ...

  3. js架构设计模式——MVC,MVP 和 MVVM 的图示及简单明了的区别说明

    MVC,MVP 和 MVVM 的图示 复杂的软件必须有清晰合理的架构,否则无法开发和维护. MVC(Model-View-Controller)是最常见的软件架构之一,业界有着广泛应用.它本身很容易理 ...

  4. oracle闪回技术总结之闪回数据库

    [实施步骤] 步骤一.设置如下的初始化参数: Sql>小时:以分钟为单位 SQL> 点00分左右发现表被删除 切了几个归档 22:00:38SQL>:06:05 SQL> :0 ...

  5. Web浏览器兼容性测试工具如何选择

    对于前端开发工程师来说,网页兼容性测试工程师而言,确保代码在各种主流浏览器的各个版本中都能正常工作是件很费时的事情,幸运的是,有很多优秀的工具可以帮助测试浏览器的兼容性,领测软件测试网向您推荐12款很 ...

  6. 使用Flex构建Web和移动参考应用程序

    范例文件 Shopping Cart Sales Dashboard Expense Tracker 需要的其他产品 Android 2.2及更高版本或Android 3.0及更高版本的设备 仅仅在F ...

  7. 微信前端面试题----js实现LazyMan

    这是微信小程序的一道面试题,题目是这样的: 实现一个LazyMan,可以按照以下方式调用:LazyMan("Hank")输出:Hi! This is Hank! LazyMan(& ...

  8. Express之托管静态文件

    中间件express.static 我们使用express初始化一个目录的时候,会在app.js中看到一大推的app.use. 其中一个主要的中间件是express.static(4.0版本依旧保留的 ...

  9. mysql学习之权限管理

    数据库权限的意义: 为了保证数据库中的业务数据不被非授权的用户非法窃取,需要对数据库的访问者进行各种限制,而数据库安全性控制措施主要有这三种,第一种用户身份鉴别,手段可以是口令,磁卡,指纹等技术,只有 ...

  10. js-tab选项卡

    说道tab选项卡,顾名思义,就是切换不同内容分类,想必学过前端的都知道,tab有很多方法可以实现,最近刚跟师傅学了一种,感觉很简便,很实用哦.    一.先看一下结果 二.可以根据图来布局,首先上面标 ...