Django|第一部

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==‘123‘:
            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

时间: 2024-08-11 05:43:09

Django|第一部的相关文章

django入门全套(第一部)

本章简介: Django 简介 Django 基本配置 Django url Django view Django 模板语言 Django Form Django Cookie Django Session Django CSRF Django 简介 Django是一个开放源代码的Web应用框架,由Python写成.采用了MVC的软件设计模式,即模型M,视图V和控制器C.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的.并于2005年7月在BSD许可证下发布.这套框架是以比

实战Django:官方实例Part1

[写在前面] 撰写这个实战系列的Django文章,是很久之前就有的想法,问题是手头实例太少,一旦开讲,恐有"无米下锅"之忧. 随着对Django学习的深入,渐渐有了些心得,把这些心得整理出来,以规范的.方便新人上手的撰写方式来写这个实战系列,相信对刚接触Django的童鞋会有一定的帮助. 舍得这里所用到的版本,为Django 1.7.1,Python 3.2,想要按照舍得讲解的实例上手练习的话,请务必与舍得所用的版本保持一致. 实例是在Windows系统下调试的,如果你采用的是非Win

实战Django:Rango Part2

  在这一节,我们将学习如何用自动脚本来添加内容,然后给我们的应用添加首页和一个内容页. 9.Part1练习答案 除了加入views和likes两个字段,这里我们需要思考一个问题,用户将如何来访问我们的页面?用/rango/category/1/ 或 /rango/category/2/?他们怎么知道1代表哪个分类,2又代表哪个分类?有没有更直接一点的方法呢? 我想还是直接用分类名称来作为链接的一部分会比较好一些,比如用/rango/category/Python/来访问Python分类这样子.

django 配置URLconf和获取值

django中正确配置url匹配找到视图: 1 在项目下的settings.py中ROOT_URLCONF = "项目名.urls" 表示 前台发来请求会先去项目下的test3/urls.py文件进行正则匹配找到应该执行的视图函数. 2 在test3/urls.py 文件中进行配置 urlpatterns 发来的请求会进入urlpatters列表顺次匹配正则表达式,匹配成功的进入url()的第二个参数指定的去向 发来请求如果是ip:端口/aaa/bbb/?a=23 类似这样的格式,到这

Django基础笔记

django随记:Django URL配置原则:松耦合原则,松耦合是一个重要的保证互换性的软件开发方法.例如urls.py 是用来配置url的     views.py是用来配置视图函数的,二者之间是松耦合的!Django中时区的设置, 在Django中加入在/home/zhou中通过django-admin.py   startproject mysite创建一个mysite的应用此时在/home/zhou文件夹下会生成一个manage.py文件,同时会有一个mysite的文件夹.  mana

Django APIView源码解析

APIView用法: 在Django之 CBV和FBV中,我们是分析的from django.views import View下的执行流程,以下是代码 from django.views import View class IndexView(View): def get(self,request, *args, **kwargs): return HttpResponse("ok") def dispatch(self, request, *args, **kwargs): ret

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

https://blog.csdn.net/guan__ye/article/details/80451318 最近接到一个任务,就是用django后端,前段用vue,做一个普通的简单系统,我就是一搞后端的,听到vue也是比较震惊,之前压根没接触过vue. 看了vue的一些文档,还有一些项目,先说一下django与vue的完美结合吧! 首先是创建一个django项目 django-admin startproject mysite # 创建mysite项目 django-admin starta

Django框架项目-电商web(未前后分离)

项目:电商订购网站 所用到框架: 语言:Python3.6.8 (Django==1.11.1) 数据库: MySql. redis 任务队列(异步处理): celery 分布式文件存储: FastDFS或者本地都行 搜索引擎(商品检索): django-haystack .whoosh web服务器配置: Nginx+ uwsgi 后台管理: django-admin 实现功能:用户模块,商品相关,购物车相关,订单相关 1. 需求分析 1.1 用户模块 注册页 注册时校验用户名是否已被注册.

Django url 标签和reverse()函数的使用(转)

原文:http://www.yihaomen.com/article/python/355.htm 使用url标签和reverse()函数,可以避免在模板和view中对url进行硬编码,这样即使url改变了,对模板和view也没有影响 起初用django 开发应用的时候,完全是在urls.py 中硬编码配置地址,在views.py中HttpResponseRedirect()也是硬编码转向地址,当然在template 中也是一样了,这样带来一个问题,如果在urls.py 中修改了某个页面的地址,