Python学习笔记_进阶篇(二)_django知识(一)

本章简介:

  • Django 简介
  • Django 基本配置
  • Django url
  • Django view
  • Django 模板语言
  • Django Form

Django 简介

Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的软件设计模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。

Django的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don’t Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和数据模型。

优点:

  • 完美的文档,Django的成功,我觉得很大一部分原因要归功于Django近乎完美的官方文档(包括Djangobook)。
  • 全套的解决方案,Django象Rails一样,提供全套的解决方案(full-stackframework + batteries included),基本要什么有什么(比如:cache、session、feed、orm、geo、auth),而且全部Django自己造,开发网站应手的工具Django基本都给你做好了,因此开发效率是不用说的,出了问题也算好找,不在你的代码里就在Django的源码里。
  • 强大的URL路由配置,Django让你可以设计出非常优雅的URL,在Django里你基本可以跟丑陋的GET参数说拜拜。
  • 自助管理后台,admin interface是Django里比较吸引眼球的一项contrib,让你几乎不用写一行代码就拥有一个完整的后台管理界面。

缺点:

  • 系统紧耦合,如果你觉得Django内置的某项功能不是很好,想用喜欢的第三方库来代替是很难的,比如下面将要说的ORM、Template。要在Django里用SQLAlchemy或Mako几乎是不可能,即使打了一些补丁用上了也会让你觉得非常非常别扭。
  • Django自带的ORM远不如SQLAlchemy强大,除了在Django这一亩三分地,SQLAlchemy是Python世界里事实上的ORM标准,其它框架都支持SQLAlchemy了,唯独Django仍然坚持自己的那一套。
  • Template功能比较弱,不能插入Python代码,要写复杂一点的逻辑需要另外用Python实现Tag或Filter。

Django流程介绍

Django采用MTV模式。所谓MVC就是把web应用分为模型(M),控制器©,视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器©接受用户的输入调用模型和视图完成用户的请求。

  • Django的MTV模式本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同,Django的MTV分别代表:
  • Model(模型):负责业务对象与数据库的对象(ORM)
  • Template(模版):负责如何把页面展示给用户
  • View(视图):负责业务逻辑,并在适当的时候调用Model和Template
  • 此外,Django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

接下来就挨个说说每个模块来构成的Django

Django 基本配置

一、创建django程序

  • 终端命令:django-admin startproject sitename
  • IDE创建Django程序时,本质上都是自动执行上述命令

1、终端命令

 # 查看django版本
$ python -m django --version

# 创建项目,名为mysite
$ django-admin startproject mysite

# 启动django
$ python manage.py runserver
$ python manage.py runserver 8080
$ python manage.py runserver 0.0.0.0:8000

# 创建应用程序,确保和 manage.py 是同一目录
$ python manage.py startapp polls

# 运行创造模型变化迁移
$ python manage.py makemigrations

# 运行应用模型变化到数据库
$ python manage.py migrate

# admin创建管理员用户
$ python manage.py createsuperuser

2、IDE创建(PyCharm为例)

File --> New Project --> 选择Django --> Appliocation Name 创建app

二、生成目录结构如下:

三、配置文件(settings)

1、刚创建django project时,开始写入程序,第一步先要在配置文件中注册app

INSTALLED_APPS = [
     'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',  # 注册app
]

2、数据库连接

DATABASES = {
     'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'数据库名',
    'USER': 'root',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}

注:由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替

如下设置放置的与project同名的配置的 init.py文件中

import pymysql
pymysql.install_as_MySQLdb() 

3、静态文件配置

STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
    )

注:需要在project下创建static文件夹

Django url

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

1、先写一个简单的世界你好吧

url文件

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
]

views文件

from django.shortcuts import render
# Create your views here.

def index(request):
    return render(request,'index.html')

templates文件夹下新建index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Hello 张岩林</h1>
</body>
</html>

2、路由正则

urlpatterns = [
    url(r '^index/(?P<pager>\d*)/,views.index,{'id':333}),
]

注:Django支持路由正则功能,同时想拿到值可以在view中的函数中把相对应得明明写入即可接收到,{‘id’:333}传入函数,通过key可以取到值

views中index函数

from django.shortcuts import render
# Create your views here.

def index(request,pager,id):
    print(pager,id)
    return render(request,'index.html')

由此看出正则这块可以写分页功能

3、app对路由规则进行一次分类

需要在app01中新建一个urls文件,然后写入,project下urls配置

from django.conf.urls import url
from django.contrib import admin
from app01 import views
from  django.conf.urls import include

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^buy/', include('app01.urls')),
]

app01下urls配置

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
]

访问url如下:

http://127.0.0.1/buy/index/

django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

Django views

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

  • http请求:HttpRequest对象

  • http响应:HttpResponse对象

一、HttpRequest对象

 # 获取提交方式
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

二、HttpResponse对象

 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",{'zhang':'好帅'})     

Django 模板语言

1、if/else
{% if %}标签计算一个变量值,如果是“true”,即它存在、不为空并且不是false的boolean值
系统则会显示{% if %}和{% endif %}间的所有内容:

{% if today_is_weekend %}   
    <p>Welcome to the weekend!</p>  
{% else %}   
    <p>Get back to work.</p>  
{% endif %}  

2、{% for %}

标签允许你按顺序遍历一个序列中的各个元素,Python的for语句语法为for X in Y,X是用来遍历Y的变量 ,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容
例如,显示给定athlete_list变量来显示athlete列表:

<ul>  
{% for athlete in athlete_list %}   
    <li>{{ athlete.name }}</li>  
{% endfor %}   
</ul>   
forloop.counter  # for循环个数  
forloop.first    # for循环第一个值  
forloop.last     # for循环最后一个值

3、母版,子版继承,导入

母板:{% block title %}{% endblock % }
子板:{% extends "base.html" %}
   {% block title %}{% endblock %}

4、自定义模板simple_tag

a、在app中创建templatetags模块

b、创建任意 .py 文件,如:xx.py

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
from django.template.base import resolve_variable, Node, TemplateSyntaxError
  
register = template.Library()
  
@register.simple_tag
def my_simple_time(v1,v2,v3):
    return  v1 + v2 + v3
  
@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

注:事例中变量名不能变,必须是固定写法

c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名

{% load xx %}

d、使用simple_tag

{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

Django Form

有时候我们需要在前台用 get 或 post 方法提交一些数据,所以自己写一个网页,用到 html 表单的知识。

一、基础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>

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

网页的值传到服务器是通过 或 标签中的 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()

我们的视图函数 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})

对应的模板文件 index.html

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

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

2、进阶案例二

models.py

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')

views.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})

在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"}))

前端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>

View Code

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/81169.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

攻防世界-PHP2

原题 解题思路 这题需要查看页面的phps文件&#xff08;这玩意从没见过&#xff09;。phps的文件是存放php的源代码的&#xff0c;但是不是所有网站都有。 只要让传入的idadmin就可以得到key了。 但是直接传入admin不行。用burp编码。 结果还是不行&#xff1a; 那就再…

【C++】做一个飞机空战小游戏(十)——子弹击落炮弹、炮弹与飞机相撞

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…

Linux笔试题(4)

67、在局域网络内的某台主机用ping命令测试网络连接时发现网络内部的主机都可以连同,而不能与公网连通,问题可能是__C_ A.主机ip设置有误 B.没有设置连接局域网的网关 C.局域网的网关或主机的网关设置有误 D.局域网DNS服务器设置有误 解析&#xff1a;在局域网络内的某台主…

视频怎么转gif高清动图?分享一款视频转gif工具

许多小伙伴都不知道如何将拍摄的短视频转gif图片&#xff0c;本文将分享一款专业的视频转gif工具&#xff0c;打来浏览器即可将视频在线转gif&#xff08;https://www.gif.cn&#xff09;&#xff0c;操作简单&#xff0c;使用方便&#xff0c;下面是详细的步骤。 打开网站&am…

linux系统服务学习(六)FTP服务学习

文章目录 FTP、NFS、SAMBA系统服务一、FTP服务概述1、FTP服务介绍2、FTP服务的客户端工具3、FTP的两种运行模式&#xff08;了解&#xff09;☆ 主动模式☆ 被动模式 4、搭建FTP服务&#xff08;重要&#xff09;5、FTP的配置文件详解&#xff08;重要&#xff09; 二、FTP任务…

实验一 VMware 17 虚拟机下安装Ubuntu16.04

系列文章目录 文章目录 系列文章目录前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 古人云&#xff1a;“工欲善其事&#xff0c;必先利其器。” 我们在学习分布式数据库原理知识同时少不了实操&#xff0c;在做实验之前&#xff0c;把相关实验…

AI 绘画Stable Diffusion 研究(十二)SD数字人制作工具SadTlaker插件安装教程

免责声明: 本案例所用安装包免费提供&#xff0c;无任何盈利目的。 大家好&#xff0c;我是风雨无阻。 想必大家经常看到&#xff0c;无论是在产品营销还是品牌推广时&#xff0c;很多人经常以数字人的方式来为自己创造财富。而市面上的数字人收费都比较昂贵&#xff0c;少则几…

解决多模块内核心模块有接口打包成jar后被依赖并调用遇到的问题(springcloud集成ruoyi.quartz)

项目准备开发个新功能&#xff0c;刚好很喜欢ruoyi写的任务调度&#xff0c;因此想到了集成ruoyi.quartz模块 &#xff0c;遇到了很多问题: 首先因为ruoyi.quartz模块依赖了ruoyi.common模块&#xff0c;因此第一步我需要把common模块一部分依赖项复制到了quartz模块内&#xf…

Python 的下一代 HTTP 客户端

迷途小书童 读完需要 9分钟 速读仅需 3 分钟 1 环境 windows 10 64bitpython 3.8httpx 0.23.0 2 简介 之前我们介绍过使用 requests ( https://xugaoxiang.com/2020/11/28/python-module-requests/ ) 来进行 http 操作&#xff0c;本篇介绍另一个功能非常类似的第三方库 httpx&…

pointnet C++推理部署--tensorrt框架

classification 如上图所示&#xff0c;由于直接export出的onnx文件有两个输出节点&#xff0c;不方便处理&#xff0c;所以编写脚本删除不需要的输出节点193&#xff1a; import onnxonnx_model onnx.load("cls.onnx") graph onnx_model.graphinputs graph.inpu…

时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现WOA-CNN-LSTM鲸鱼算法优化卷积长短期记忆神经网络时间序列预测预测效果基本介绍模型描述程序设计学习总结参考资料 预测效果 基本介绍 时序预测 | MATLAB实现WOA-…

VBA技术资料MF45:VBA_在Excel中自定义行高

【分享成果&#xff0c;随喜正能量】可以不光芒万丈&#xff0c;但不要停止发光。有的人陷入困境&#xff0c;不是被人所困&#xff0c;而是自己束缚自己&#xff0c;这时"解铃还须系铃人"&#xff0c;如果自己无法放下&#xff0c;如何能脱困&#xff1f; 。 我给V…

03_缓存双写一致性

03——缓存双写一致性 一、缓存双写一致性 如果redis中有数据&#xff0c;需要和数据库中的值相同如果redis中无数据&#xff0c;数据库中的值要是最新值&#xff0c;且准备回写redis 缓存按照操作来分&#xff0c;可以分为两种&#xff1a; 只读缓存 读写缓存 同步直写操作…

解决:(error) ERR unknown command shutdow,with args beginning with

目录 一、遇到问题 二、出现问题的原因 三、解决办法 一、遇到问题 要解决连接redis闪退的问题&#xff0c;按照许多的方式去进行都没有成功&#xff0c;在尝试使用了以下的命名去尝试时候&#xff0c;发现了这个问题。 二、出现问题的原因 这是一个粗心大意导致的错误&am…

Azure静态网站托管

什么是静态网站托管 Azure Blob的静态网站托管是一项功能&#xff0c;它允许开发人员在Azure Blob存储中托管和发布静态网站。通过这个功能&#xff0c;您可以轻松地将静态网页、图像、视频和其他网站资源存储在Azure Blob中&#xff0c;并直接通过提供的URL访问这些资源。 官…

什么是变量提升(hoisting)?它在JavaScript中是如何工作的?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 变量提升&#xff08;Hoisting&#xff09;⭐ 变量提升的示例&#xff1a;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&…

Android 场景Scene的使用

Scene 翻译过来是场景&#xff0c;开发者提供起始布局和结束布局&#xff0c;就可以实现布局之间的过渡动画。 具体可参考 使用过渡为布局变化添加动画效果 大白话&#xff0c;在 Activity 的各个页面之间切换&#xff0c;会带有过渡动画。 打个比方&#xff0c;使用起来类似…

回归预测 | MATLAB实现IPSO-SVM改进粒子群优化算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现IPSO-SVM改进粒子群优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现IPSO-SVM改进粒子群优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xf…

保险龙头科技进化论:太保的六年

如果从2013年中国首家互联网保险公司——众安在线的成立算起&#xff0c;保险科技在我国的发展已走进第十个年头。十年以来&#xff0c;在政策指引、技术发展和金融机构数字化转型的大背景下&#xff0c;科技赋能保险业高质量发展转型已成为行业共识。 大数据、云计算、人工智…

unity 之Transform组件(汇总)

文章目录 理论指导结合例子 理论指导 当在Unity中处理3D场景中的游戏对象时&#xff0c;Transform 组件是至关重要的组件之一。它管理了游戏对象的位置、旋转和缩放&#xff0c;并提供了许多方法来操纵和操作这些属性。以下是关于Transform 组件的详细介绍&#xff1a; 位置&a…