vth的django探险1

上一节我们走完了用django开发的基本流程,现在我们可以逐步求精,彻底搞懂django怎么用了。

0x00 Web框架职责

  1. 充当socket服务端
  2. 根据URL不同返回不同的内容
  3. 返回给用户符合HTTP协议的字符串

所有的web框架都要做到这几个职责的一点或者多点。
django做到了2和3。django没有自己的socket server, 用的python的wsgiref模块。

我们的B/S架构到底是个什么玩意儿?
broswer充当socket客户端,server充当socket服务端,仅此而已。
所谓的broswer,只不过是功能非常强大的socket客户端,他的本质就是socket客户端。

0x01 Django的安装和使用

公共步骤:

pip3 install django

说句题外话,python的安装目录下有个叫Scripts的目录。
这个目录被加到了环境变量之中。所以我们才能直接在命令行用这个目录下的程序。
我们来看看这个目录下都有啥:
在这里插入图片描述
题外话结束。------
命令行方式创建django工程:

django-admin startproject mysite

pycharm方式创建django工程(需要pycharm专业版):

file—> New Project —>
在这里插入图片描述

手动启动django项目(在manage.py的同级目录下执行):

python manage.py runserver 127.0.0.1:8080

pycharm启动django项目:
在这里插入图片描述
选中之后,按绿色播放键即可。

0x02 django项目的目录结构

$ tree mysite
mysite
├── db.sqlite3 # 数据库文件
├── manage.py # 对当前django项目的所有操作都可以用manage.py
├── mysite # 存放django项目主配置、主路由的目录
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── settings.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── wsgi.cpython-37.pyc
│   ├── asgi.py
│   ├── settings.py # django项目配置文件
│   ├── urls.py # 路由系统  url--->业务逻辑
│   └── wsgi.py # django用的socket server. 调用的wsgiref接口,开发用, 性能略差。以后可以用uwsgi, ngnix等
└── templates

其中我们无需关注pyc结尾的。因为这相当于是编译过的。

0x03 django初体验

我们来写第一个业务逻辑。(只是示例用,工作中把业务逻辑写在路由里会被人当场打死)
首先说一下版本差异:
django1.x 用的是:

from django.conf.urls import url

而django2.x用的是:

from django.urls import path

有啥区别呢?
Django1的url支持正则匹配:

  • 'article-(\d+).html':使用正则表达式的分组匹配来获取URL中的参数,并以位置参数形式传递给视图article。
  • 'article-(?P<article_id>\d+).html':使用正则表达式的分组命名匹配来获取URL中的参数,并以关键字参数的形式传递给视图article。
  • 分组命名正则表达式组的语法是:(?P<name>pattern),其中name是组的名称(视图中的关键字参数必须跟组名一致),pattern是正则表达式。

django1的url示例:

from django.conf.urls import url

# 使用url关键字
urlpatterns = [
    url('article-(\d+).html',views.article),
    url('article-(?P<article_id>\d+).html',views.article)
]
# url请求地址为:http://127.0.0.1:8000/article-1.html

Django2的path:

  • path写的是绝对字符串,请求地址必须与路由地址完全匹配
  • 使用尖括号 <> 从url中获取参数值
  • 可以使用转换器指定参数类型,例如: <int:age> 捕获一个整数参数age,若果没有转化器,将匹配任何字符串,也包括路径分隔符 /

path拥有5个转换器:

  • str:匹配除路径分隔符 / 外的字符串
  • int:匹配自然数
  • slug:匹配字母,数字,横杠及下划线组成的字符串
  • uuid:匹配uuid形式的数据
  • path:匹配任何字符串,包括路径分隔符 /

总而言之,别管是django2还是django1的路由系统,要做的事情就是将url与业务逻辑代码匹配上,只是实现的方式略有不同。
django2更简单一些。

django2示例:

from django.urls import path

# 使用path关键字
urlpatterns = [
    path('article-<int:article_id>.html',views.article),
]
# url请求地址为:http://127.0.0.1:8000/article-1.html

OK, 来写一个例子:

# urls.py
from django.urls import path
from django.shortcuts import HttpResponse


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    return HttpResponse('vth')


urlpatterns = [
    path('login/', login)
]

在这里插入图片描述
其中,HttpResponse是一个类。我们返回时要返回它的对象。
我们对对象进行构造的时候,只需要把内容放到构造器里即可。就如上面代码所示。

0x04 发现问题—难道要这样写前端页面?

学会了上述知识,我们开心的去写返回给前端的页面了。

#urls.py
from django.urls import path
from django.shortcuts import HttpResponse


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    return HttpResponse('<h1>vth的标题</h1>')


urlpatterns = [
    path('login/', login)
]

我们这次返回的是h1标签。
然而我们发现,要是写很复杂很复杂的页面,那咋整???
我们成功的由后端开发工程师转型成全栈了???

4.1 使用模板

没有没有,django怎么会这么low。我们可以直接返回html文件。

我们想返回html文件只需要三步:

  1. urls.py中引入把index.html渲染成HttpResponse的函数
  2. templates下新建index.html
  3. urls.py中返回render函数渲染的index.html

urls.py

#urls.py
from django.urls import path
from django.shortcuts import HttpResponse, render


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    # return HttpResponse('<h1>vth的标题</h1>')
    return render(requests, 'index.html')


urlpatterns = [
    path('login/', login)
]

templates/index.html

<!--templates/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vth的小酒馆</title>
</head>
<body>
    <h1>vth的标题</h1>
</body>
</html>

看下效果:
在这里插入图片描述
完全ok。新技能get.

but, 心虚不??为啥在templates目录下新建, django就能找到这个文件?
我们觉得templates难听,就要用xxxxx, 行不行?

解决django在哪找文件,属于django的配置问题,所以我们应该去settings.py找。
在这里插入图片描述
这里和存放templates的目录是一样的。也就是说是从这里配置的。

4.2 使用CSS

OK,这个问题解决了。我们又提出了新的需求。
前端代码,HTML负责骨架,CSS负责美容。那么,我们想写CSS怎么写?众所周知我们有3大引入方式。为了代码的可读性,我们打算用文件引入的方式来写CSS。

首先我们应该得给CSS单独弄个目录吧,以后好管理。取名叫style吧。
弄好后的目录结构是这样的:

$ tree mysite
mysite
├── db.sqlite3
├── manage.py
├── mysite
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── settings.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── wsgi.cpython-37.pyc
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── style
│   └── index.css
└── templates
    └── index.html

CSS的内容如下:

h1{
    color: red;
}

然后我们修改index.html,让它引入这个css文件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vth的小酒馆</title>
    <link href="/static/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <h1>vth的标题</h1>
</body>
</html>

我们的href中写的是/static/index.css, 先不用care这点。

然后我们刷新下页面,发现没变。意思是我们写的css并没有生效。那咋整? 代表着django找不到我们写的css。所以这还是个配置问题。如法炮制,去settings.py改。
拉到最下面,改成这样:
在这里插入图片描述
我们新加了STATICFILES_DIRS。 它是一个元组。元素为字符串。
第二个参数style就是我们存放静态文件CSS的目录了。

加好后我们刷新页面,发现CSS已经能发挥作用了。
在这里插入图片描述
咦?还记得为啥我们的index.html中要写成:/static/index.css么?
解释一下,STATIC_URL是一个静态的URL地址,我们在引入文件时,它应当充当前缀。
我们虽然写的是static, 但是由于我们配置了STATICFILES_DIRS, 所以django明白实际上应该去styleCSS文件。

0x05 写个登录示例

开干吧。
首先我们修改index.html, 改造成表单。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vth的小酒馆</title>
    <link href="/static/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <h1>vth的标题</h1>
    <form method="POST" action="/login/">
        <input type="text" name="user">
        <input type="password" name="pwd">
        <input type="submit" value="登录">
    </form>
</body>
</html>

注意,action后面的/login//不能省。不然会报错。

然后我们修改我们的业务逻辑。
因为在打开一个页面的时候用的是get方法,所以我们可以认为页面使用的是get方法时为未登录状态,返回给它登录页面。
如果是post方法,就验证帐号密码对不对,如果对,重定向到百度。如果不对,则返回登录页面。

#urls.py
from django.contrib import admin
from django.urls import path
from django.shortcuts import HttpResponse, render, redirect


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    if requests.method == 'GET':
        # get请求
        return render(requests, 'index.html')
    elif requests.method == 'POST':
        print(requests.POST)
        if requests.POST.get('user') == 'vth' and requests.POST.get('pwd') == '123':
            # 登录成功
            return redirect('http://www.baidu.com')
        else:
            # 帐号密码错误
            return render(requests, 'index.html')

urlpatterns = [
    path('login/', login)
]

5.1 requests中的属性总结

method: 标识着请求用的是http的什么方法
POST: 去请求体中拿数据,请求体中的数据是KV对,所以这里面也是KV对。用什么就用POST的get方法拿什么
GET: 从请求的url中拿数据,也是KV对,取值方式同上。

5.2 可返回的值的类型总结

HttpResponse('str')
这里返回的是一个HttpResponse对象,我们只需要把字符串丢进去即可。
render(requests, 'xxx.html', {'name':'test'})
这里返回的是被第三个参数渲染的第二个参数的模板文件。
redirect('url')
这里返回的是一个重定向的url.重定向到谁就写谁。

0x06 jinja2 模板渲染规则

6.1 普通字符串渲染

模板中用{{name}}, python代码render的时候,传一个字典,字典要包含name这个key, 字典中name这个key对应的value类型为字符串。

<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vth的小酒馆</title>
    <link href="/static/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <h1>{{ name }}</h1>
</body>
</html>
# urls.py
from django.urls import path
from django.shortcuts import HttpResponse, render, redirect


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    return render(requests, 'index.html', {'name':'vth'})
urlpatterns = [
    path('login/', login)
]

效果:
在这里插入图片描述

6.2 value为列表的渲染

模板中写{{name.index}}, python代码中写 {'name':['a','b']}.

我们来修改一下代码:

<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vth的小酒馆</title>
    <link href="/static/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <h1>{{ name.0 }}</h1>
    <h1>{{ name.1 }}</h1>
</body>
</html>
# urls.py
from django.urls import path
from django.shortcuts import HttpResponse, render, redirect


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    return render(requests, 'index.html', {'name':[
        'vth',
        'ygm'
    ]})
urlpatterns = [
    path('login/', login)
]

在这里插入图片描述

6.3 value为字典的渲染

说一个概念。在前端的世界里,数组的下标和字典的Key,都叫Index. 所以在jinja2中的使用方式跟数组是一样的。

<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vth的小酒馆</title>
    <link href="/static/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <h1>{{ name.age }}</h1>
    <h1>{{ name.sex }}</h1>
</body>
</html>
from django.urls import path
from django.shortcuts import HttpResponse, render, redirect


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    return render(requests, 'index.html', {'name':{
        'age': 18,
        'sex': '男'
    }})
urlpatterns = [
    path('login/', login)
]

在这里插入图片描述
诶?等等??难不成只能这么low???不能遍历吗? 当然可以!

6.4 遍历列表的渲染

首先来说一下遍历的语法:

{% for item in name %}
    {{ item }}
{% endfor %}

其中,for in endfor 是关键字。
来看一下:

<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vth的小酒馆</title>
    <link href="/static/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <div>
        {% for item in name %}
        <h1>{{ item }}</h1>
        {% endfor %}
    </div>
</body>
</html>
# urls.py
from django.urls import path
from django.shortcuts import HttpResponse, render, redirect


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    return render(requests, 'index.html', {'name':[
        'vth','ygm'
    ]})
urlpatterns = [
    path('login/', login)
]

在这里插入图片描述

6.5 遍历字典的渲染

规则:

{% for key, value in row.items %}
	{{ key }}  {{ value }}      
{% endfor %}

示例:

<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vth的小酒馆</title>
    <link href="/static/index.css" rel="stylesheet" type="text/css"/>
</head>
<body>
    <div>
        {% for key,value in name.items %}
        <h1>{{ key }} -----  {{ value }}</h1>
        {% endfor %}
    </div>
</body>
</html>
# urls.py
from django.urls import path
from django.shortcuts import HttpResponse, render, redirect


def login(requests):
    '''
    处理用户请求,并返回内容
    :param requests: 用户请求相关的所有信息, object
    :return:
    '''
    return render(requests, 'index.html', {'name':{
        'age': 18,
        'sex': '男'
    }})
urlpatterns = [
    path('login/', login)
]

在这里插入图片描述

6.6 jinja2的最牛B之处

jinja2最牛B的地方就在于它可以跟html混搭。如6.5所示,我们可以在html标签里写jinja2语法,jinja2的语法之中也可以有html标签。

6.7 特别提醒

jinja2的for循环边界,{%%}应该紧挨着,不能有空格,不然就SB了。

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值