Python(17)——Django框架入门-项目创建与认识子应用


0、前言(预备知识)

0.1 HTTP协议的认识

什么是HTTP 协议?
HTTP协议就是客户端和 服务器端之间数据传输的格式规范,格式简称为“超文本传输协议”。

  • 基于 TCP/IP
    • HTTP是一个属于应用层的面向对象的协议。
    • HTTP协议工作于客户端-服务端架构上。
  • 基于请求-响应模式
    • 浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
    • Web服务器根据接收到的请求后,向客户端发送响应信息。
      在这里插入图片描述

为什么说Http 协议是无状态协议?

HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行
保存。

在这里插入图片描述

怎么解决Http 协议无状态协议?
无状态协议解决办法:

  • 通过Cookie
  • 通过Session会话保存。
    在这里插入图片描述

Http请求中常见的请求方式

根据 HTTP 标准,HTTP 请求可以使用多种请求方法。

  • HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
  • HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方
    法。

在这里插入图片描述

0.2 MVC模式和MTV模式

MVC 模式

  • MVC 就是把Web应用分为模型(M),控制器©和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射( ORM ),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求。
    在这里插入图片描述

MTV 模式

  • MTV模式本质上和 MVC 是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,在Python的世界中,基本(除了Pylons)都使用了 MVC 的变种 MTV (Model Templates View 模型-模板-视图)。

  • Django 的MTV分别是值:

    • M 代表模型(Model): 负责业务对象和数据库的关系映射( ORM )。
    • T 代表模板 (Template):负责如何把页面展示给用户( html )。
    • V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
  • 除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示
    在这里插入图片描述

1、框架介绍

1.1 什么是框架?

  • 软件框架就是为实现或完成某种软件开发时,提供了一些基础的软件产品,
  • 框架的功能类似于 基础设施 ,提供并实现最为 基础的软件架构和体系
  • 通常情况下我们依据框架来实现更为复杂的业务程序开发
  • 二个字,框架就是程序的 骨架

1.2 Python 中常见的框架有哪些?

  • 大包大揽 Django 被官方称之为完美主义者的Web框架。
  • 力求精简 web.py 和 Tornado
  • 新生代微框架 Flask 和 Bottle

1.3 Django 框架介绍

  • Django 是一个高级的Python Web框架,它鼓励快速开发和清洁,务实的设计。
  • 由经验丰富的开发人员构建,它负责Web开发的许多麻烦,因此您可以专注于编写应用程序,而
  • 无需重新创建轮子。
  • 免费的和开源的。
  • 被官方称之为完美主义者的Web框架。
    官方网址

1.4 Django 框架的特点

在这里插入图片描述

1.5 Django 可以使用什么Python版本?

在这里插入图片描述
Django 的开发版本
在这里插入图片描述

1.6 Django 的安装

在线安装Django,指定版本安装
pip install django==2.2

2、Django快速入门:后台管理

Django官方使用文档

2.1 打开pycharm,新建django项目,目录自定义

在这里插入图片描述
django项目目录
在这里插入图片描述
目录说明:

manage.py :一个命令行工具,可以使你用多种方式对 Django 项目进行交互
内层的目录:项目的真正的Python包
__init__.py :一个空文件,它告诉Python这个目录应该被看做一个Python包
settings.py :项目的配置
urls.py :项目的URL声明
wsgi.py :项目与 WSGI 兼容的Web服务器入口

2.2 使用terminal端口试运行django

python manage.py runserver   ## 默认8000端口
##此命令不可以补全
python manage.py runserver 9999 ## 指定端口运行
python manage.py runserver & 后台运行

在这里插入图片描述

在这里插入图片描述

前面命令不可以自动补齐,非常不方便,这里利用tools运行即可补齐命令,很好用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 创建一个子应用程序

Django 自带一个实用程序,可以自动生成应用程序的基本目录结构,因此您可以专注于编写代码而不是创建目录。

在一个项目中可以创建一到多个应用,每个应用进行一种业务处理

python manage.py startapp bookApp  ##创建一个名为bookApp的应用

在这里插入图片描述

在这里插入图片描述
应用的目录结构如下图 :

在这里插入图片描述

2.3.0 数据库基本创建与连接以及迁移(后面数据库模型会详解)

  • 在 settings.py 文件中,通过DATABASES项进行数据库设置
  • Django 支持的数据库包括: sqlite 、 mysql 等主流数据库
  • Django 默认使用 SQLite 数据库

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
数据库迁移
使用这些 Django 自带的应用程序,需要我们在数据库中创建一些数据表对应,然后才能使用它们。

python manage.py makemigrations ## 生成迁移文件
python manage.py migrate  ##数据库迁移
## 每次数据库内容发生变化都需要此命令更新

在这里插入图片描述
在这里插入图片描述

2.3.1 编写第一个视图函数

编辑 bookApp/views.py

from django.shortcuts import render
from django.http import  HttpResponse
# Create your views here.
def index(request):
    print("用户请求",request.path)
    return HttpResponse('首页信息')

2.3.2 编写路由规则

url() 函数介绍:

  • Django url() 可以接收四个参数,分别是两个必选参数: regex 、 view 和两个可选参数:kwargs 、 name 。
 regex : 正则表达式,与之匹配的 URL 会执行对应的第二个参数 view。
 view : 用于执行与正则表达式匹配的 URL 请求。
 kwargs : 视图使用的字典类型的参数。
 name : 用来反向获取 URL。

查看setting.py文件:
在这里插入图片描述
根据主配置文件settings 可知路由查找的主文件的urls.py ,因此在该文件添加一条 url 规则(读子应用的urls配置文件),这样是比较推荐的一种方法,可以避免主文件的urls.py 中路由策略过多。
在这里插入图片描述

在这里插入图片描述
去子应用bookApp中新建urls.py文件

from django.urls import path
from bookApp import views
from bookApp.views import index

urlpatterns = [
  path(r'', views.index, name= 'index'),
]

在这里插入图片描述

2.3.3 测试

在这里插入图片描述
利用html语言修改访问字体的大小与夜色测试:

from django.shortcuts import render
 # Create your views here. 
from django.http import HttpResponse def index(request):
    return HttpResponse('<h1 style="color:red">图书管理系统</h1>')

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4 项目的数据库模型

2.4.1 数据库基本创建与连接

  • 在 settings.py 文件中,通过DATABASES项进行数据库设置
  • Django 支持的数据库包括: sqlite 、 mysql 等主流数据库
  • Django 默认使用 SQLite 数据库

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.4.2 创建数据库模型

- 本示例完成“图书-英雄”信息的维护,需要存储两种数据:图书、英雄
	图书表结构设计: 表名: Book
		图书名称: title
		图书发布时间: pub_date
	英雄表结构设计: 表名: Hero
		英雄姓名: name
		英雄性别: gender
		英雄简介: hcontent
		所属图书: hbook
	图书-英雄的关系为一对多
from django.db import models
"""
名词: 
    ORM(Object Ralational Mapping,对象关系映射)用来把对象模型表示的对象映射到基于S Q L 的关系模型数据库结构中去。
    这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的 SQ L 语句打交道,只需简单的操作实体对象的属性和方法。
一对多关系:外键写在多的一端
book:hero = 1:n
"""
# Create your models here.
# bookApp/models.py   ##找对文件的相应书写位置

# 类对应数据库表, 表名称默认为bookApp_book.
class Book(models.Model):
    # 属性对应数据库表的列名,默认会添加id这一列。
    name = models.CharField(max_length=40, verbose_name="书籍名称")
    pub_date = models.DateField(verbose_name="出版日期")

    # 魔术方法,字符串友好展示, 便于调试代码
    def __str__(self):
        return  self.name
# 类对应数据库表, 表名称默认为bookApp_hero.
class Hero(models.Model):
    ## 属性对应数据库表的列名,默认会添加id这一列
    gender_choice = [
        (1,"男"),
        (2,"女")
    ]
    name = models.CharField(max_length=20,verbose_name="人物名称")
    #性别只能选择男或女
    gender = models.IntegerField(choices=gender_choice,verbose_name="性别")
    content = models.TextField(max_length=1000,verbose_name="人物描述")
    ##外键关联,如果删除书籍时,相关hero对应的书籍设置为空
    book_id = models.ForeignKey(Book,on_delete=models.SET_NULL,null=True,verbose_name="书籍id")

在这里插入图片描述

2.4.3 生成数据库表

1. 激活模型:编辑 settings.py 文件,将应用加入到 INSTALLED_APPS 中
2. 生成迁移文件:根据模型类生成 sql 语句
	终端执行命令: python manage.py makemigrations
3. 执行迁移:执行 sql 语句生成数据表
	终端执行命令: python manage.py migrate

1)激活模型
在这里插入图片描述
2)生成迁移文件
在这里插入图片描述
在这里插入图片描述
迁移文件内容

# Generated by Django 3.1.7 on 2021-03-14 04:08

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Book',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=40, verbose_name='书籍名称')),
                ('pub_date', models.DateField(verbose_name='出版日期')),
            ],
        ),
        migrations.CreateModel(
            name='Hero',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=20, verbose_name='人物名称')),
                ('gender', models.IntegerField(choices=[(1, '男'), (2, '女')], verbose_name='性别')),
                ('content', models.TextField(max_length=1000, verbose_name='人物描述')),
                ('book_id', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='bookApp.book', verbose_name='书籍id')),
            ],
        ),
    ]

3)执行迁移
在这里插入图片描述
在这里插入图片描述

2.4.4 数据库模型基本操作(操作指令可以在官网模型层查找)

 E:\BookManage>python manage.py shell
In [1]: from bookApp.models import Book,Hero

In [2]: ##1.查询数据

In [3]: Book.objects.all()
Out[3]: <QuerySet []>

In [4]: ##2.增加数据
In [6]: from datetime import date

In [7]: b1 = Book(name="西游记",pub_date=date(1000,1,1))

In [8]: b2 = Book(name="红楼梦",pub_date=date(1000,2,2))

In [9]: b1.save()

In [10]: b2.save()

In [11]: Book.objects.all()
Out[11]: <QuerySet [<Book: 西游记>, <Book: 红楼梦>]>

In [12]: #3.根据条件搜索并查看

In [13]: b1 = Book.objects.filter(name="西游记")

In [14]: b1
Out[14]: <QuerySet [<Book: 西游记>]>

In [15]: b1 = Book.objects.filter(name="西游记").first()

In [16]: b1
Out[16]: <Book: 西游记>

In [17]: b1.pub_date
Out[17]: datetime.date(1000, 1, 1)

In [18]: ##4.删除数据

In [19]: b1.delete()
Out[19]: (1, {'bookApp.Book': 1})

In [20]: Book.objects.all()
Out[20]: <QuerySet [<Book: 红楼梦>]>


##In [23]: #5.创建关联对象

In [24]: b3 = Book(name="倚天屠龙记", pub_date=date(1000,1,2))  ##创建书籍

In [25]: b3.save()   ##保存

In [26]: hero1 = Hero(name="周芷若",gender=2,content="info...")  ##定义英雄

In [27]: hero1.save()  ##保存

In [28]: Hero.objects.all()
Out[28]: <QuerySet [<Hero: 周芷若>]>

In [29]: hero1.book_id = b3    ##指定hero1属于哪本书

In [30]: hero1.book_id
Out[30]: <Book: 倚天屠龙记>

In [31]: hero1.book_id_id
Out[31]: 3

In [32]: b3.hero_set.all()
Out[32]: <QuerySet []>

In [38]: b3.hero_set.all()
Out[38]: <QuerySet [<Hero: 周芷若>]>
##另一种关联对象的方式
b3.hero_set.create(name="张无忌",
gender=True,
content="武当派第二代“张五侠”张翠山与天鹰教紫微堂堂主殷素素的儿子")


##6.一些简单操作
In [42]: books = Book.objects.filter(name__contains="红")  ##查找包含红的
In [43]: books
Out[43]: <QuerySet [<Book: 红楼梦>]>
In [44]: books = Book.objects.exclude(name__contains="红")  ##查找不包含红的书
In [45]: books
Out[45]: <QuerySet [<Book: 倚天屠龙记>]>

在这里插入图片描述

在这里插入图片描述

2.5 启用后台Admin 站点管理(图形化管理2.4.4数据库增删改查)

  • 站点分为“内容发布(后台管理)”和“公共访问(前台管理)”两部分
  • “内容发布”部分负责添加、修改、删除内容,开发这些重复的功能是一件单调乏味、缺乏创造力的工作。
  • Django会根据定义的模型类完全自动地生成管理模块。

Django 框架中有一个非常强大的应用功能: 自动管理界面。常被Web平台管理者使用,去管理整个Web平台。

默认情况下,在 settings.py 配置文件中INSTALLED_APPS包含以下应用程序,为了后续的开发,默认这些应用程序都是包含在里面的

在这里插入图片描述

2.5.1 创建管理员用户

# 按提示输入用户名、邮箱、密码
python manage.py createsuperuser
  • 启动服务器,通过 “127.0.0.1:8000/admin” 访问,输入上面创建的用户名、密码完成登录
  • 进入管理站点,默认可以对 groups、users 进行管理

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述

2.5.2 管理界面本地化

编辑 settings.py 文件,设置编码、时区

改为中文
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'

在这里插入图片描述

2.5.3 自定义模型加入后台管理

刷新管理页面,可以对 Book 的数据进行增删改查操作 ;

  • 问题一: python2 版本中, 如果在 str 方法中返回中文,在修改和添加时会报 ascii 的错误
    在 str() 方法中,将字符串末尾添加 “.encode(‘utf-8’)” 进行字符串编码
  • 问题二: 后台管理时, Book管理显示的是英文, 如何变成中文?
1、首先确保服务跑起来E:\BookManage>python manage.py runserver

2、打开 bookApp/admin.py 文件,注册模型
admin.site.register(Book,Hero)

3、中文显示
# bookApp/models.py
class Book(models.Model):
#class类中加入下面代码:meta的详细操作可以官网查找
class Meta:
db_table = "books"
# 单数时显示的名称
verbose_name = '图书信息'
# 复数时显示的名称
verbose_name_plural = '图书信息'

4、修改完成网页自动更新

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

测试结果:
在这里插入图片描述

2.5.4 自定义管理页面

  • Django 提供了 admin.ModelAdmin 类
  • 通过定义 ModelAdmin 的子类,来定义模型在 Admin 界面的显示方式

修改bookApp.admin.py文件,内容如下:

from django.contrib import admin
from bookApp.models import Book,Hero
# Register your models here.
##书籍自定义管理界面
    # list_display:显示字段,可以点击列头进行排序
    # list_filter:过滤字段,过滤框会出现在右侧
    # search_fields:搜索字段,搜索框会出现在上侧
    # list_per_page:分页,分页框会出现在下侧
class BookAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'pub_date']
    list_filter = ['pub_date']
    search_fields = ['name']
    list_per_page = 5
##人物自定义管理界面
class HeroAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'gender']
    list_filter = ['gender']
    search_fields = ['name','content']
    list_per_page = 5
    # 添加、修改页属性
    # fields:属性的先后顺序   fields = ['pub_date', 'title']
    #fields = ['gender', 'content']
    # fieldsets :属性分组, 注意: fields和fieldsets 只能设置一个.
    fieldsets = [('必填信息', {'fields': ['name','book_id']}),
                 ('选填信息', {'fields': ['gender','content']}),]
admin.site.register(Book, BookAdmin)
admin.site.register(Hero, HeroAdmin)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

关联对象
对于 Hero 模型类,有两种注册方式

  • 方式一:与 Book 模型类相同
  • 方式二:关联注册
    • admin.StackedInline : 内嵌关联注册类(观看效果更佳)
    • admin.TabularInline : 表格 关联注册类

修改bookApp.admin.py文件,内容如下:

from django.contrib import admin
from bookApp.models import Book,Hero
# Register your models here.
##书籍自定义管理界面
    # list_display:显示字段,可以点击列头进行排序
    # list_filter:过滤字段,过滤框会出现在右侧
    # search_fields:搜索字段,搜索框会出现在上侧
    # list_per_page:分页,分页框会出现在下侧
class HeroInline(admin.StackedInline):  
    model = Hero      ##关联的模块要写对
    extra = 3         ##一次性增加的个数
class BookAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'pub_date']
    list_filter = ['pub_date']
    search_fields = ['name']
    list_per_page = 5
    inlines = [HeroInline]    ##关联英雄模块
##人物自定义管理界面
class HeroAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'gender']
    list_filter = ['gender']
    search_fields = ['name','content']
    list_per_page = 5
    # 添加、修改页属性
    # fields:属性的先后顺序   fields = ['pub_date', 'title']
    #fields = ['gender', 'content']
    # fieldsets :属性分组, 注意: fields和fieldsets 只能设置一个.
    fieldsets = [('必填信息', {'fields': ['name','book_id']}),
                 ('选填信息', {'fields': ['gender','content']}),]
admin.site.register(Book, BookAdmin)
admin.site.register(Hero, HeroAdmin)

在这里插入图片描述
在这里插入图片描述

3、Django快速入门: 前台管理

3.1 第一步: URLconf 路由管理

  • 在 Django 中,定义 URLconf 包括正则表达式、视图两部分 。
  • Django 使用正则表达式匹配请求的URL,一旦匹配成功,则调用应用的视图 。
  • 注意:只匹配路径部分,即除去域名、参数后的字符串 。
  • 在主配置文件中添加子配置文件,使主 urlconf 配置连接到子模块的 urlconf 配置文件

主配置文件(主路由指向子路由)配置如下, 已经配置过, 可以忽略此步骤:

# BookManage/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
url(r'book/', include('bookApp.urls')),
#当用户访问的url地址以book开头, 请访问bookApp.urls这个url配置文件进行匹配并执行对应的视图函数.
]

在这里插入图片描述

bookApp 子应用的子配置文件(子路由)如下:

# bookApp/urls.py
urlpatterns = [
# 当用户访问bookApp应用的主页时, 执行视图函数index,反向根据名称获取url地址;
url(r'^$', views.index, name='index'),
# 显示书籍的详情页
url(r'^([0-9]+)/$', views.detail, name='detail'),
]

在这里插入图片描述

3.2 第二步: 视图函数处理业务逻辑

  • 在 Django 中,视图对WEB请求进行回应( response )。
  • 视图接收 reqeust 请求对象作为第一个参数,包含了请求的信息 。
  • 视图函数就是一个Python函数,被定义在 views.py 中 。
  • 定义完成视图后,需要配置 urlconf ,否则无法处理请求。
from django.shortcuts import render
from django.http import HttpResponse
from bookApp.models import Book
# Create your views here.

#视图:对用户的请求(request)进行业务逻辑操作,最终返回给用户一个response
from django.http import HttpResponse
def index(request):
    #print("用户请求的路径:",request.path)
    books = Book.objects.all()
    #返回响应信息
    #return HttpResponse("图书管理系统")
    #渲染,将上下文content{'books':books}填充到book/index.html代码的过程
    return render(request,'book/index.html',{'books':books})
def detail(request,id):
    """书籍详情页信息"""
    book = Book.objects.filter(id=id).first()
    pub_date = book.pub_date
    heros = book.hero_set.all()
    return render(request,'book/detail.html',{'book':book,'heros':heros})

在这里插入图片描述

3.3 第三步: 模板管理实现好看的HTML页面

  • 作为Web 框架, Django 需要一种很便利的方法以动态地生成HTML。最常见的做法是使用模板。
  • 模板包含所需HTML 输出的静态部分,以及一些特殊的语法,描述如何将动态内容插入。

3.3.1 模板引擎配置

创建模板的目录如下图:
在这里插入图片描述
修改 BookManage/settings.py 文件,设置 TEMPLATES 的 DIRS 值

在这里插入图片描述

3.3.2 模板语法: 变量

  • 变量输出语法
{ { var } }
  • 当模版引擎遇到一个变量,将计算这个变量,然后将结果输出。
  • 变量名必须由字母、数字、下划线(不能以下划线开头)和点组成。
  • 当模版引擎遇到点("."),会按照下列顺序查询:
    • 字典查询,例如: foo[“bar”]
    • 属性或方法查询,例如: foo.bar
    • 数字索引查询,例如: foo[bar]
  • 如果变量不存在, 模版系统将插入’’ (空字符串)。

3.3.3 模板语法: 常用标签

  • 语法
{ % tag % }
  • 作用
    • 在输出中创建文本。
    • 控制循环或逻辑。
    • 加载外部信息到模板中。

for标签

{% for ... in ... %}
循环逻辑
{% endfor %}

if标签

{% if ... %}
逻辑1
{% elif ... %}
逻辑2
{% else %}
逻辑3
{% endif %}

comment标签

{% comment %}
多行注释
{% endcomment %}

include标签

  • 加载模板并以标签内的参数渲染
{% include "base/left.html" %}

url :反向解析

{% url 'name' p1 p2 %}

csrf_token 标签

  • 用于跨站请求伪造保护
{% csrf_token %}

3.3.4 主页与详情页前端HTML设计

在这里插入图片描述
在这里插入图片描述
测试:
在这里插入图片描述
在这里插入图片描述

3.3.5 html常用模板标签示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1 style="color: blueviolet">图书管理系统</h1>
<ul>
    {%  for book in books %}
        <li><a href="/book/{{ book.id }}/">{{ book.name }}</a></li>
    {% endfor %}
</ul>
</body>
</html>

4.Django请求的生命周期

wsgi : 封装请求后交给后端的web框架( Flask、Django )。
请求中间件: 对请求进行校验或在请求对象中添加其他相关数据,例如: csrf、
request.session 。
路由匹配: 根据浏览器发送的不同 url 去匹配不同的视图函数。
视图函数: 在视图函数中进行业务逻辑的处理,可能涉及到: ORM、Templates 。
响应中间件: 对响应的数据进行处理。
wsgi : 将响应的内容发送给浏览器。

在这里插入图片描述
在这里插入图片描述

总结

  • 本系统基本功能已经完成, 前端页面可以搜索好看的 html 进行替换。
  • 安装配置 django 运行的环境
  • 编写模型,使用简单 API 与数据库交互
  • 使用 Django 的后台管理中维护数据
  • 通过 视图 接收请求,通过模型获取数据,展示出来
  • 调用模板完成展示

作业

  • 设计 一对多 关系的两个模型类 : 博客和博客分类
  • 使用 django 后台管理
  • 通过视图、 urlconf 、模板完成数据的展示
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值