django框架菜鸟教程_django框架菜鸟教程

2022-10-05 08:44:19 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

Django

一、介绍

1、简介

是用python语言写的开源web开发框架,并遵循MVC设计。

Django的主要目的是简便、快速的开发数据库驱动的网站。

2、特点

1) 重量级框架

2)MVT模式

  • MVC
    • 其核心思想是分工、解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。
    • M全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。
  • V全拼为View,用于封装结果,生成页面展示的html内容。
  • C全拼为Controller,用于接收请求,处理业务逻辑,与Model和View交互,返回结果。
  • MVT
    • M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理。
    • V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
    • T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html。

二、工程搭建

1、创建工程

创建工程命令

代码语言:javascript复制
django-admin startproject 工程名称

工程目录说明

  • settings.py 是项目的整体配置文件。
  • urls.py 是项目的URL配置文件。
  • wsgi.py 是项目与WSGI兼容的Web服务器入口。
  • manage.py 是项目管理文件,通过它管理项目

运行开发服务器

代码语言:javascript复制
python manage.py runserver ip:端口
或:python manage.py runserver
# 可以不写IP和端口,默认IP是127.0.0.1,默认端口为8000

2、创建子应用

创建

代码语言:javascript复制
python manage.py startapp 子应用名称

# 例如创建一个user子应用模块
'''
cd ~/Desktop/code/demo
python manage.py startapp users
'''

子应用目录说明

  • admin.py 文件跟网站的后台管理站点配置相关。
  • apps.py 文件用于配置当前子应用的相关信息。
  • migrations 目录用于存放数据库迁移历史文件。
  • models.py 文件用户保存数据库模型类。
  • tests.py 文件用于开发测试用例,编写单元测试。
  • views.py 文件用于编写Web应用视图。

注册安装子应用

代码语言:javascript复制
注册安装一个子应用的方法,即是将子应用的配置信息文件apps.py中的Config类添加到INSTALLED_APPS列表中。
# 例如
'''
INSTALLED_APPS = [
    ...
    'users.apps.UsersConfig',
]
'''

3、创建视图

创建

代码语言:javascript复制
# 在views.py中编写视图代码
from django.http import HttpResponse

def index(request):
    """
    index视图
    :param request: 包含了请求信息的请求对象
    :return: 响应对象
    """
    return HttpResponse("hello the world!")
'''
说明:
1、视图函数的第一个传入参数必须定义,用于接收Django构造的包含了请求数据的HttpReqeust对象,通常名为request。
2、视图函数的返回值必须为一个响应对象,不能像Flask一样直接返回一个字符串,可以将要返回的字符串数据放到一个HTTPResponse对象中。
'''

定义路由URL

  1. 在子应用中新建一个urls.py文件用于保存该应用的路由。
  2. 在users/urls.py文件中定义路由信息。 from django.conf.urls import url from . import views urlpatterns是被django自动识别的路由列表变量 urlpatterns = [ # 每个路由信息都需要使用url函数来构造 # url(路径, 视图) url(r’^index/$’, views.index), ]
  3. 在工程总路由demo/urls.py中添加子应用的路由数据。
代码语言:javascript复制
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),  # django默认包含的

    # 添加
    url(r'^users/', include('users.urls')), 
]
# 使用include来将子应用users里的全部路由包含进工程路由中
# r'^users/' 决定了users子应用的所有路由都已/users/开头,如我们刚定义的视图index,其最终的完整访问路径为/users/index/。
# include函数除了可以传递字符串之外,也可以直接传递应用的urls模块
  1. 启动运行 python manage.py runserver

三、配置、静态文件与路由

1、 配置文件

BASE_DIR

代码语言:javascript复制
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  • 当前工程的根目录,Django会依此来定位工程内的相关文件,我们也可以使用该参数来构造文件路径。

DEBUG

  • 调试模式,创建工程后初始值为True,即默认工作在调试模式下。
  • 作用:
    • 修改代码文件,程序自动重启
    • Django程序出现异常时,向前端显示详细的错误追踪信息.
  • 注意:部署线上运行的Django不要运行在调式模式下,记得修改DEBUG=False .

本地语言与时区

  • 中国大陆地区使用简体中文,时区使用亚洲/上海时区 LANGUAGE_CODE = ‘zh-hans’ # 语言 TIME_ZONE = ‘Asia/Shanghai’ # 时区

2、静态文件

  • 推荐放在项目的根目录下,方便管理。
  • 为了提供静态文件,需要配置两个参数:
    • STATICFILES_DIRS 存放查找静态文件的目录
    • STATIC_URL 访问静态文件的URL前缀
  • 示例 1) 在项目根目录下创建static_files目录来保存静态文件。 2) 在demo/settings.py中修改静态文件的两个参数为 STATIC_URL = ‘/static/’ STATICFILES_DIRS = [ os.path.join(BASE_DIR, ‘static_files’), ] 3)此时在static_files添加的任何静态文件都可以使用网址 /static/文件在static_files中的路径 来访问了。
  • 注意 Django 仅在调试模式下(DEBUG=True)能对外提供静态文件。 当DEBUG=False工作在生产模式时,Django不再对外提供静态文件,需要是用collectstatic命令来收集静态文件并交由其他静态文件服务器来提供。

3、路由说明

路由定义位置

  • Django的主要路由信息定义在工程同名目录下的urls.py文件中,该文件是Django解析路由的入口。
  • 每个子应用为了保持相对独立,可以在各个子应用中定义属于自己的urls.py来保存该应用的路由。然后用主路由文件包含各应用的子路由数据。

路由解析顺序

  • Django在接收到一个请求时,从主路由文件中的urlpatterns列表中以由上至下的顺序查找对应路由规则,如果发现规则为include包含,则再进入被包含的urls中的urlpatterns列表由上至下进行查询。
  • 值得关注的由上至下的顺序,有可能会使上面的路由屏蔽掉下面的路由,带来非预期结果。 需要注意定义路由的顺序,避免出现屏蔽效应。

路由命名与reverse反解析(逆向)

路由命名

  1. 在使用include函数定义路由时,可以使用namespace参数定义路由的命名空间,如 url(r’^users/’, include(‘users.urls’, namespace=‘users’)), 命名空间表示,凡是users.urls中定义的路由,均属于namespace指明的users名下。 命名空间的作用:避免不同应用中的路由使用了相同的名字发生冲突,使用命名空间区别开。
  2. 在定义普通路由时,可以使用name参数指明路由的名字,如 urlpatterns = [ url(r’^index/$’, views.index, name=‘index’), url(r’^say’, views.say, name=‘say’), ]

reverse反解析 使用reverse函数,可以根据路由名称,返回具体的路径,如: from django.urls import reverse # 注意导包路径

代码语言:javascript复制
def index(request):
    return HttpResponse("hello the world!")

def say(request):
    url = reverse('users:index')  # 返回 /users/index/
    print(url)
    return HttpResponse('say')
  • 对于未指明namespace的,reverse(路由name)
  • 对于指明namespace的,reverse(命名空间namespace:路由name)

路径结尾斜线/的说明

Django中定义路由时,通常以斜线/结尾,其好处是用户访问不以斜线/结尾的相同路径时,Django会把用户重定向到以斜线/结尾的路径上,而不会返回404不存在 。

代码语言:javascript复制
urlpatterns = [
    url(r'^index/$', views.index, name='index'),
]

四、请求与相应

1、请求

1)URL路径参数

可以使用正则表达式提取参数的方法从URL中获取请求参数,直接传递到视图的传入参数中。

  • 未命名参数按定义顺序传递 url(r’^weather/([a-z] )/(d{4})/$’, views.weather), def weather(request, city, year): print(‘city=%s’ % city) print(‘year=%s’ % year) return HttpResponse(‘OK’)
  • 命名参数按名字传递 url(r’^weather/(?P[a-z] )/(?Pd{4})/$’, views.weather), def weather(request, year, city): print(‘city=%s’ % city) print(‘year=%s’ % year) return HttpResponse(‘OK’)

2)QueryDict对象

定义在django.http.QueryDict

HttpRequest对象的属性GET、POST都是QueryDict类型的对象

QueryDict类型的对象用来处理同一个键带有多个值的情况

  • 方法get():根据键获取值 dict.get(‘键’,默认值) 可简写为 dict[‘键’] # 说明: # 如果一个键同时拥有多个值将获取最后一个值 # 如果键不存在则返回None值,可以设置默认值进行后续处理
  • 方法getlist():根据键获取值,值以列表返回,可以获取指定键的所有值 如果键不存在则返回空列表[],可以设置默认值进行后续处理 dict.getlist(‘键’,默认值)

3)查询字符串

通过request.GET属性获取,返回QueryDict对象。

代码语言:javascript复制
# /qs/?a=1&b=2&a=3

def qs(request):
    a = request.GET.get('a')
    b = request.GET.get('b')
    alist = request.GET.getlist('a')
    print(a)  # 3
    print(b)  # 2
    print(alist)  # ['1', '3']
    return HttpResponse('OK')

# 重要:查询字符串不区分请求方式,即假使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。

4)请求体

请求体数据格式:表单类型字符串、JSON字符串、XML字符串

请求方式:POST/PUT/PATCH/DELETE

表单类型 通过request.POST属性获取,返回QueryDict对象。 def get_body(request): a = request.POST.get(‘a’) b = request.POST.get(‘b’) alist = request.POST.getlist(‘a’) print(a) print(b) print(alist) return HttpResponse(‘OK’) # 重要:request.POST只能用来获取POST方式的请求体表单数据。

非表单类型 通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。request.body返回bytes类型。 # 请求体中的数据 {“a”: 1, “b”: 2}

代码语言:javascript复制
import json

def get_body_json(request):
    json_str = request.body
    json_str = json_str.decode()  # python3.6 无需执行此步
    req_data = json.loads(json_str)
    print(req_data['a'])
    print(req_data['b'])
    return HttpResponse('OK')

请求头

request.META为字典类型。

常见的请求头:

  • CONTENT_LENGTH – The length of the request body (as a string).
  • CONTENT_TYPE – The MIME type of the request body.
  • HTTP_ACCEPT – Acceptable content types for the response.
  • HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.
  • HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.
  • HTTP_HOST – The HTTP Host header sent by the client.
  • HTTP_REFERER – The referring page, if any.
  • HTTP_USER_AGENT – The client’s user-agent string.
  • QUERY_STRING – The query string, as a single (unparsed) string.
  • REMOTE_ADDR – The IP address of the client.
  • REMOTE_HOST – The hostname of the client.
  • REMOTE_USER – The user authenticated by the Web server, if any.
  • REQUEST_METHOD – A string such as “GET” or “POST”.
  • SERVER_NAME – The hostname of the server.
  • SERVER_PORT – The port of the server (as a string). 具体使用: def get_headers(request): print(request.META[‘CONTENT_TYPE’]) return HttpResponse(‘OK’)

其他

  • method:一个字符串,表示请求使用的HTTP方法,常用值包括:‘GET’、‘POST’。
  • user:请求的用户对象。
  • path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
  • encoding:一个字符串,表示提交的数据的编码方式。
    • 如果为None则表示使用浏览器的默认设置,一般为utf-8。
    • 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
  • FILES:一个类似于字典的对象,包含所有的上传文件。

2、响应

HttpResponse

django.http.HttpResponse来构造响应对象

代码语言:javascript复制
HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)

HttpResponse子类

Django提供了一系列HttpResponse的子类,可以快速设置状态码

  • HttpResponseRedirect 301
  • HttpResponsePermanentRedirect 302
  • HttpResponseNotModified 304
  • HttpResponseBadRequest 400
  • HttpResponseNotFound 404
  • HttpResponseForbidden 403
  • HttpResponseNotAllowed 405
  • HttpResponseGone 410
  • HttpResponseServerError 500

JsonResponse

  • 返回json字符串
  • 设置响应头Content-Type为 application/json

redirect重定向

代码语言:javascript复制
from django.shortcuts import redirect

def demo_view(request):
    return redirect('/index.html')

3、Cookie

特点:

  • 键值对格式的字符串,存储于浏览器中
  • 基于域名安全,不同域名的Cookie是不能互相访问的,同源策略
  • 浏览器会将cookie信息包含在请求报文中,发给服务器

设置Cookie

代码语言:javascript复制
HttpResponse.set_cookie(cookie名, value=cookie值, max_age=cookie有效期)
#  max_age 单位为秒,默认为None。如果是临时cookie,可将max_age设置为None。

读取Cookie

可以通过HttpRequest对象的COOKIES属性来读取本次请求携带的cookie值。request.COOKIES为字典类型。

代码语言:javascript复制
def demo_view(request):
    cookie1 = request.COOKIES.get('itcast1')
    print(cookie1)
    return HttpResponse('OK')

删除

request.delete_cokkie(键)

4、Session

  • 写:request.session[‘键’]=值
  • 读:request.session.get(‘键’,默认值)
    • 删除值:request.session.clear()
    • 删除整条数据:request.session.flush()
    • 删除指定的键及值:del request.sessioon[‘键’]
  • 设置有效期:request.session.set_expiry(value)
    • 如果value是一个整数,session将在value秒没有活动后过期。
    • 如果value为0,那么用户session的Cookie将在用户的浏览器关闭时过期。
    • 如果value为None,那么session有效期将采用系统默认值,默认为两周,可以通过在settings.py中设置SESSION_COOKIE_AGE来设置全局默认值。

五、类视图与中间件

1、类视图

定义:使用类来定义的视图

好处:

  • 可读性好
  • 更高的复用性

使用 from django.view.generic import View 配置路由时,使用类视图的as_view()方法来添加

原理 在注册路由规则时类.as_view()返回方法名 在请求路径与正则匹配成功后,方法会被执行 调用dispatch()方法 根据请求方式名称获取方法 执行方法

使用装饰器

在URL配置中装饰 此种方法会为类视图中的所有请求方法都加上装饰器行为,不建议使用

类视图中装饰 method_decorator装饰器使用name参数指明被装饰的方法 # 为全部请求方法添加装饰器 @method_decorator(my_decorator, name=‘dispatch’) class DemoView(View): def get(self, request): print(‘get方法’) return HttpResponse(‘ok’)

代码语言:javascript复制
    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

# 为特定请求方法添加装饰器
@method_decorator(my_decorator, name='get')
class DemoView(View):
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')
        
    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

如果需要为类视图的多个方法添加装饰器,但又不是所有的方法(为所有方法添加装饰器参考上面例子),可以直接在需要添加装饰器的方法上使用method_decorator from django.utils.decorators import method_decorator

代码语言:javascript复制
# 为特定请求方法添加装饰器
class DemoView(View):

    @method_decorator(my_decorator)  # 为get方法添加了装饰器
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

    @method_decorator(my_decorator)  # 为post方法添加了装饰器
    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

    def put(self, request):  # 没有为put方法添加装饰器
        print('put方法')
        return HttpResponse('ok')

类视图Mixin扩展类

2、中间件

Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。

代码实现 定义一个中间件工厂函数,然后返回一个可以别调用的中间件。 中间件工厂函数需要接收一个可以调用的get_response对象。 返回的中间件也是一个可以被调用的对象,并且像视图一样需要接收一个request对象参数,返回一个response对象。 def simple_middleware(get_response): # 此处编写的代码仅在Django第一次配置和初始化的时候执行一次。

代码语言:javascript复制
    def middleware(request):
        # 此处编写的代码会在每个请求处理视图前被调用。

        response = get_response(request)

        # 此处编写的代码会在每个请求处理视图之后被调用。

        return response

    return middleware

定义好中间件后,需要在settings.py 文件中添加注册中间件 MIDDLEWARE = [ … ‘users.middleware.my_middleware’, # 添加中间件 ] 注意:Django运行在调试模式下,中间件init部分有可能被调用两次。

执行流程

  • 在请求视图被处理前,中间件由上至下依次执行
  • 在请求视图被处理后,中间件由下至上依次执行

六、模板

1、配置

settings.py配置文件中修改TEMPLATES中的DIRS

2、定义

3、渲染

  • 调用模板两步骤:
    • loader.get_template(模板文件在模板目录中的相对路径)–> 返回模板对象
    • 模板对象.render(contex=None,request=None)–>返回渲染后的html文本字符串
  • Django提供了一个函数render可以简写上述代码。
    • render(request对象, 模板文件路径, 模板数据字典) from django.shortcuts import render def index(request): context={‘city’: ‘北京’} return render(request,‘index.html’,context)

4、语法

{ {变量}}-变量

{%for%}…{%endfor%}

{%if%}…{%elif%}…{%else%}…{%endif%}

== != < > <= >=比较运算符

and or not布尔运算符

注意:运算符左右两侧不能紧挨变量或常量,必须有空格

变量|过滤器:参数过滤器

  • safe,禁用转义,告诉模板这个变量是安全的,可以解释执行
  • length,长度,返回字符串包含字符的个数,或列表、元组、字典的元素个数。
  • default,默认值,如果变量不存在时则返回默认值。
  • date,日期,用于对日期类型的值进行字符串格式化,常用的格式化字符如下:
    • Y表示年,格式为4位,y表示两位的年。
    • m表示月,格式为01,02,12等。
    • d表示日, 格式为01,02等。
    • j表示日,格式为1,2等。
    • H表示时,24进制,h表示12进制的时。
    • i表示分,为0-59。
    • s表示秒,为0-59。 value|date:“Y年m月j日 H时i分s秒” {#…#}单行注释 {%comment%}…{%endcomment%}多行注释

5、模板继承

父模板:{%block%}…{%endblock%}

子模板:{%extends “父模板路径”%}

写在子模板文件的第一行

七、数据库

ORM框架:

  • 通过类和类对象就能操作它对所对应的表格中的数据
  • 根据设计的类自动生成数据库中的表格

数据库迁移:

  1. python manage.py makemigrations
  2. python manage.py migrate

数据库的操作

1.增

  • save 对象.save()
  • create 模型类.objects.create()

2.查

基本查询

  • get 查询单一结果,不存在抛出 模型类.DoesNotExist 异常
  • all 多个结果
  • count 查询结果数量

过滤查询

  • filter 过滤多个结果
  • exclude 排除
  • get 过滤单一结果

过滤条件的表达语法 属性名称__比较运算符=值

  • exact
  • contains
  • startwith、endwith
  • isnull
  • in
  • gt/gte/lt/lte
  • year/month/day/week_day/hour/minute/second

F对象 F( 属性名) 属性比较

Q对象 Q(属性名__运算符=值) 实现逻辑或or的查询,需要使用Q()对象结合|运算符 Q对象前可以使用~操作符,表示非not # 例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现 from django.db.models import Q BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))

聚合函数 使用aggregate()过滤器调用聚合函数,返回字典类型的数据

  • Avg
  • Count
  • Max
  • Min
  • Sum

排序

  • order_by
  • 默认升序,-降序

关联查询

一到多:一对应的模型类对象.多对应的模型类名小写_set b = BookInfo.objects.get(id=1) b.heroinfo_set.all()

多到一:多对应的模型类对象.多对应的模型类中的关系属性名 h = HeroInfo.objects.get(id=1) h.hbook

访问一对应的模型类关联对象的id 多对应的模型类对象.关联类属性_id

关联过滤查询

由多模型类条件查询一模型类数据: 关联模型类名小写__属性名__条件运算符=值

代码语言:javascript复制
#  例句:查询图书,要求图书中英雄的描述包含"八"
BookInfo.objects.filter(heroinfo__hcomment__contains='八')

由一模型类条件查询多模型类数据: 一模型类关联属性名__一模型类属性名__条件运算符=值

代码语言:javascript复制
# 查询图书阅读量大于30的所有英雄
HeroInfo.objects.filter(hbook__bread__gt=30)

3.改

  • save
  • update 使用模型类.objects.filter().update(),会返回受影响的行数

4.删

  • 模型类对象delete
  • 模型类.objects.filter().delete()

查询集 QuerySet

1、概念:从数据库中获取的对象集合

过滤器方法:

  • all()
  • filter()
  • exclude()
  • order_by()
  • exists():判断查询集中是否有数据,有返回Ture,无返回False

2、特性

  • 惰性执行:创建查询集的时候不会调用数据库,调用数据的时候访问,迭代、序列化、if合用
  • 缓存

3、限制查询集

对查询集进行下标或切片操作,切片后返回新的查询集,不会立即执行

管理器Manageer

1、自定义管理器

  • 修改原始查询集,重写all()方法
    • booktest/models.py文件中 #图书管理器 class BookInfoManager(models.Manager): def all(self): #默认查询未删除的图书信息 #调用父类的成员语法为:super().方法名 return super().filter(is_delete=False)
    • 在模型类BookInfo中定义管理器 class BookInfo(models.Model): … books = BookInfoManager()
    • 使用方法 BookInfo.books.all()
  • 在管理器类中补充定义新的方法
    • 打开booktest/models.py文件,定义方法create
    • 为模型类BookInfo定义管理器books语法如下
    • 调用方法

八、Admin

使用

1、管理界面本地化

代码语言:javascript复制
settings.py中设置语言和时间

2、创建超级管理员

代码语言:javascript复制
python manage.py createsuperuser

> 修改密码:
>
> python manage.py changepassword 用户名

3、App应用配置

代码语言:javascript复制
在settings.py中INSTALLED_APPS列表中添加此类

4、注册模型类

代码语言:javascript复制
# 在booktest/admin.py 文件中编写代码:
from django.contrib import admin
from booktest.models import BookInfo,HeroInfo

admin.site.register(BookInfo)
admin.site.register(HeroInfo)

5、定义与使用Admin管理类

定义:继承自admin.ModelAdmin

使用:

  • 注册参数 admin.site.register(BookInfo,BookInfoAdmin)
  • 装饰器 @admin.register(BookInfo) class BookInfoAdmin(admin.ModelAdmin): pass

编辑

1、调整列表页展示

页大小:list_per_page = 100

操作选项的位置:

  • actions_on_top = True
  • actions_on_bottom = True

列表中的列:list_display = [模型字段1,模型字段2]

将方法作为列:short_description属性 # models.py中: class BookInfo(models.Model): … def pub_date(self): return self.bpub_date.strftime(’%Y年%m月%d日’)

代码语言:javascript复制
    pub_date.short_description = '发布日期'  # 设置方法字段在admin中显示的标题
    
#  admin.py中:
class BookInfoAdmin(admin.ModelAdmin):
    ...
    list_display = ['id','btitle','pub_date']
    
# 说明:
方法列是不能排序的,需要排序:
admin_order_field = 模型类字段

关联对象 在模型类中封装方法,访问关联对象的成员

右侧栏过滤器:list_filter = []

搜索框:search_fields = []

2、调整编辑页展示

  • 显示字段:fields = []
  • 分组显示: fieldset=( (‘组1标题’,{‘fields’:(‘字段1’,‘字段2’)}), (‘组2标题’,{‘fields’:(‘字段3’,‘字段4’)}), )
  • 关联对象
    • 类型InlineModelAdmin:表示在模型的编辑页面嵌入关联模型的编辑
    • 子类TabularInline:表格的形式嵌入
    • 子类StackedInline:块的形式嵌入

3、调整站点信息

  • admin.site.site_header 设置网站页头
  • admin.site.site_title 设置页面标题
  • admin.site.index_title 设置首页标语

4、上传图片

pip install Pillow==4.1.0

配置 MEDIA_ROOT=os.path.join(BASE_DIR,“static_files/media”)

模型类添加字段 class BookInfo(models.Model): … image = models.ImageField(upload_to=‘booktest’, verbose_name=‘图片’, null=True)

代码语言:javascript复制
# upload_to 指明该字段的图片保存在MEDIA_ROOT目录中的哪个子目录

数据库迁移: python manage.py makemigrations python manage.py migrate

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

0 人点赞