一文入门Django主要组件视图、路由、模版、模型、orm、admin

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

第一个项目

app是什么

应用是一个专门做某件事的网络应用程序:比如博客系统,或者公共记录的数据库,或者简单的投票程序

项目则是一个网站使用的配置和应用的集合。项目可以包含很多个app应用,应用可以被很多个项目使用

app创建

python manage.py startapp myapp

app目录

admin.py # app在admin注册展示时需要的文件
views.py # app的功能视图函数文件
models.py # app需要使用数据库时的文件
urls.py # 当使用include路由分发时,每个app应该有他自己的子路由文件,这个是默认没有创建好的

视图函数

打开app下的views.py文件;Web访问起始就是通过一个URL连接地址访问到服务器上的一个函数

views.py中我们通过编写函数的形式,接收用户请求的request并返回一个response

# 每一个视图函数都需要有一个必须参数 request,用来接收用户访问时的请求内容
from django.http import HttpResponse

def index(request):
    return HttpResponse("<h1>Hello world</h1>")
# HttpResponse函数用来向用户返回一个字符串

路由配置

创建好了一个可以在请求时返回H1标签的视图函数,但是现在通过浏览器还是访问不到,需要我们为这个app下的函数进行路由配置;

  • 第一种简单的路由配置,直接在主控路由文件下,找到这个视图函数
#myproject/urls.py
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
    path('admin/', admin.site.urls), # admin控制界面路由
    path('',views.index),
    # path函数第一个参数为访问地址,空字符串代表:当用户直接访问首页时
    # 第二个参数代表访问该地址时对应的视图函数,我们引入了app下的views中的index视图函数
]

接下来访问127.0.0.1:8000,那么你会看到一个非常大的Hello world


以上将视图函数的查找直接写到主控路由并不是最好的办法;我们的项目通常会有非常多的路由配置项,如果都堆到这个文件中肯定是非常乱的,难以维护

  • 我们可以在对应app下创建一个子路由控制文件,并在其中设置视图的路由配置
#myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
    path("",views.index)
]

现在虽然配置了app下的路由文件,但是访问时,是看不到对应视图的结果

这是因为默认的url查找动作将会从主控路由文件开始,我们还需要在主控路由文件下进行路由分发设置

  • 让主控路由可以找到子app下的路由映射文件
#myproject/urls.py
from django.contrib import admin
from django.urls import path,include
from myapp import views
urlpatterns = [
    path('admin/', admin.site.urls),
    #path('',views.index)
    path('',include("myapp.urls")),
    # 函数 include() 允许引用其它 URLconfs
]

接下来再次尝试,在浏览器中访问主机域名;如果可以看到的话,恭喜你,效果已经很棒了!


路由查找流程

  1. 查找主控路由文件下的urlpatterns全局变量,这是一个序列数据类型,其中每一个元素都是对应的一个路由匹配规则
  2. 如果在规则中查找到符合匹配规则的,则执行其中的对应执行函数
  3. 如果对应的不是一个执行函数,而是一个include路由包含,那么截断与此项匹配的URL的部分,并将剩余的路由字符串发送到include所包含的子路由文件中以供进一步处理
  4. 如果没有匹配到的任何结果,django默认抛出Page not found (404)
  • 注意Django的路由不考虑HTTP请求方式,仅根据URL进行路由,即,只要URL相同,无论POSTGET等哪种请求方式都指向同一个操作函数

path

path函数用来处理一个路由对应的视图映射

path(route, view, name)
'''
route: 匹配规则,是一个字符串
view:对应的视图函数
name:未来我们会用到他,用来为匹配规则命名,这样方便日后修改路由而不影响全局下的路由使用
'''

  • 注意:匹配模式的最开头不需要添加/,因为默认情况下,每个url都带一个最前面的/,既然大家都有的部分,就不用浪费时间特别写一个了,所以一定要注意在写路由映射关系时,记得加末尾的/

模板页面

返回一个字符串这肯定是不行的,太low了,也不好看,现在来返回一个正式的HTML页面

并在HTML页面中加入模板变量,由视图函数动态传递值;

  • 配置django中模板页面的保存路径,在项目目录下的settings.py文件中
#myproject/settings.py
TEMPLATES = [
    {
    
    
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'template')], # 就是这一行 设置静态模板路径
        'APP_DIRS': True,
        'OPTIONS': {
    
    
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
  • 创建template目录并在其中创建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hi</title>
</head>
<body>
    <h1>{
   
   { message }}</h1>
</body>
</html>

HTML页面中,我们并没有明确指出H1标签的内容;通过一个{ { message }}来等待接收视图函数传来的数据,在HTML页面中这样的变量也叫做模板变量,双大括号为使用语法

  • 接下来修改之前的视图函数,由视图函数传递变量给到HTML页面
#myapp/views.py
from django.shortcuts import render
def index(request):
    #return HttpResponse("<h1>Hello world</h1>")
    content = {
    
    
        "message":"你好,世界" #此处的key值message对应页面中我们写的{
    
    { message }}
        }
    return render(request,'index.html',content)

render函数用来返回一个模板页面,并将一个字典组合成的模板变量传递到模板页面上,完成页面的渲染

render(request, template_name, context=None) # 返回一个HTTP响应
'''
request: 固定接收request请求
template_name: 为一个可以找到的模板页面
context: 模板页面所需模板变量
'''

django中的HTML页面,不光可以编写原本的标签等内容,还可以像Vue一样在页面中使用双大括号,来提前定义一些模板变量,之后动态的渲染到HTML模板页面中

模板变量可以由后台视图函数构建一个字典数据类型传递

context = {
    
    
	'username': '张三'
}
# 字典的key是模板变量名
# value值该模板变量对应的数据

静态文件

虽然有了模板页面,可以来展示一些标签的效果,但是整个HTML还是感觉很丑陋

我们还要继续引入一些类似css、img这样的静态资源,来装饰我们的页面;在django中模板页面的静态资源使用,不能像之前写HTML代码直接引入

需要我们首先在项目中创建目录保存对应的静态资源,该目录名常为static

  • settings中配置静态文件保存目录,添加如下内容
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
# STATICFILES_DIRS 该配置项用来告诉django在查找静态资源时,应该访问哪个目录
  • 在项目中创建static目录,static目录下创建专门保存图片的img目录,在里面存一张图片1.jpg
#此时的目录结构
myproject/
    myproject/
    myapp/
    template/
    static/
          img/
             1.jpg
  • 有了图片,接下来在模板页面中去引入并使用它,打开index.html进行修改
<!DOCTYPE html>
<html lang="en">
    {% load staticfiles %}
<head>
    <meta charset="UTF-8">
    <title>hi</title>
</head>
<body>
    <h1>{
   
   { message }}</h1>
    <img src='{% static "img/1.jpg" %}' alt="图片">
</body>
</html>

这里用到了一个特殊语法:{% tag %} 这个叫静态标签,静态标签不同于模板变量,静态标签经常用来加载数据,或创建逻辑,比如之后我们要学到的{% if %},使用静态标签可以方便我们在模板页面上实现某些只有在后台代码中才可以实现的逻辑功能


在页面中要引入静态资源:图片,CSSJS文件在引入时都需要通过{% static "path" %}来进行引入

  • 注意:需要使用静态标签static前使用**{% load staticfiles %}**标签进行静态资源路径的加载

模型数据库

什么是ORM

orm映射关系,是django与数据库之间的一个桥梁,可以使开发者不再关注如何去编写SQL语句,直接通过一套ORM所提供的API接口即可方便对各种数据库进行交互


有了以上内容的修饰,现在感觉还是缺少一些什么,我们在视图函数中为前端页面返回的是一个提前定义好的变量,这显然在真正开发中是很少出现的,我们的数据大都来自于数据库中

那么现在需要我们在项目中加入数据库,并且在视图函数中通过对数据库的访问来拿到数据

创建数据库,这里使用项目自带的SQLite3数据库,默认已经是配置好的,接下来需要我们进入到app下的models.py文件中,编写一个类,这个类就对应数据库中的一张表

  • 通过orm映射在models.py文件中创建模型类
#myapp/models.py
from django.db import models

# Create your models here.
class Weather(models.Model):
    weather = models.CharField(max_length=100,verbose_name="天气")
    class Meta:
        verbose_name_plural = "天气"
        # 设置当前表名的一个可读的性更好的名字
    def __str__(self):
        return self.weather

在这里我们使用到了djangoorm映射关系用来创建数据库表,继承自djangomodels.Model类,

一个类用来表示一张表,类中的一个属性代表一个字段

代码中定义了一个类型为CharField,长度为100的字段,用来存储天气

models.CharField(max_length=100,verbose_name="天气")

下面的class Meta是模型类的元类,用来设置当前表的一些属性;使用verbose_name_plural属性设置当前表在admin后台查看时的名字

代码中定义一个属于实例的函数__str__,用来描述当前数据在返回时的默认展示结果,为weather字段的值

django在创建模型类对应的数据表时,默认使用应用名下划线模型类名作为表的名字;比如当前Weather表名为:myapp_Weather


  • 当某个子应用APP涉及到了数据库的使用时,要记得在settings文件中进行配置
#myproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
]
  • 接下来通过manage.py命令行管理工具提供的两条,创建我们所需要的数据

注意:默认django本身就已经需要一些数据的创建,所以我们在初次执行以下两条命令时可能会看到很多数据表和字段的创建,不要惊讶,这是正常的

python manage.py migrate # 根据数据库迁移文件生成对应SQL语句并执行
python manage.py makemigrations # 创建数据库迁移文件

如果提示结果正常,那么代表相应的数据表已经创建好了;接下来就需要我们去到django为我们提供的admin(数据库管理界面)来进行相关表的操作了!

admin控制台

admin控制台是django为我们提供的一个非常便捷的用来管理数据库的界面

在主控路由文件下,其实你已经看到了它对应的路由设置:path('admin/', admin.site.urls),

进入admin界面,初次访问连接:127.0.0.1/admin,会提示我们输入账号密码,这是因为djangoadmin界面是需要一个超级管理员来登陆访问的,所以还需要我们创建对应的admin界面下的超级用户

  • 创建admin超级用户,使用manage.py命令行工具执行如下命令
python manage.py createsuperuser 
Username (leave blank to use 'lienze'): root
Email address:
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Password:
Password (again):
This password is too common.
This password is entirely numeric.
Password:
Password (again):
Superuser created successfully.

在输入太短(不满足8位),或是只包含数字的简单密码,超级用户的创建都是被拒绝的

  • 接下来开启测试服务器,并通过创建好的超级用户登陆访问,如果幸运的话,你已经可以看到后台的admin界面啦

admin界面已经展示出了默认django所使用的两张表,用户表和组表,用来保存当前管理后台的用户以及对应权限分组,可以点入用户表查看其中我们刚创建的root

model注册admin

问题还是有的,虽然admin界面已经可以登入,但是为什么看不到刚才创建的Weather表呢

这是因为默认的表创建之后,还需要通过对应app下的admin.py文件进行admin后台注册,只有注册在这个文件中的模型类对应的表才可以在admin界面所看到

  • app下的admin.py文件中进行模型类的注册
#myapp/admin.py
from django.contrib import admin
from myapp import models

admin.site.register(models.Weather)
#使用register函数接收模型类作为参数即可完成注册

注册成功之后,在服务器,通过浏览器访问admin界面,就可以看到创建好的Weather表了

  • 鼠标点击进去之后,就可以看到对应的表数据界面;右上角提供了可以添加功能的选项,试试给这个表来一些数据吧,这里我们添加了三条数据
阴天,晴天,打雷了

视图操作模型

最终我们希望可以在视图函数中通过orm接口来访问到表中的数据,那么来打开视图文件吧:views.py

#myapp/views.py
from django.shortcuts import render
from myapp import models
def index(request):
    
    weathers = models.Weather.objects.all()
    content = {
    
    
        "weathers":weathers,
    }
    return render(request, 'index.html', content)
  • 光返回是不行的,虽然我们绑定到了模板版变量的字典中,但是还得修改一下对应的要渲染的HTML页面哦:
<!DOCTYPE html>
<html lang="en">
    {% load staticfiles %}
<head>
    <meta charset="UTF-8">
    <title>hi</title>
</head>
<body>
    {% for weather in weathers %}
        <p>{
   
   { weather }}</p>
    {% empty %}
        <p>没有任何天气</p>
    {% endfor %}
</body>
</html>

模板标签{% for xxx in xxxs %}可以用来在模板页面出迭代访问取出每一个数据

{% empty %}标签用来判断当循环访问数据为空时要做的事情,最后循环标签要有{% endfor %}标签进行结束;因为HTML中并没有像Python缩进这样的方式来控制代码块。

猜你喜欢

转载自blog.csdn.net/HeroicLee/article/details/121182109