Django
原本用myclient,现在卸载了 换成pymysql
在项目_init_.py里写以下
import pymysql
pymysql.install_as_MySQLdb()
===================================================
#下载django
pip install django
#在终端切换到你的代码目录
cd .\Desktop\code
#创建项目
django-admin startproject
django-admin startproject zhonghui(项目名)
#打开项目目录
cd .\zhonghui\
zhonghui
_init_.py 书名
asgi.py
settings.py是项目的整体配置文件。
urls.py是项目的URL配置文件。
wsgi.py是项目与WSGI兼容的Web服务器入口。
manage.py是项目管理文件,通过它管理项目。
#运行项目
python manage.py runserver
#运行不成功改端口
python manage.py runserver 9000
#创建应用
python manage.py startapp courses
注册应用到项目当中
1.在settings.py里找到 INSTALLED_APPS在里头加上 'courses.apps.CoursesConfig' (应用里的apps.py下的类)
在models.py里构建模型Teacher,Course,Student,TeacherAssistant
进行数据库配置
1. 在setting里找到DATABASES
'ENGINE'下的sqlite3改为mysql,'NAME'改为数据库名字,并添加除这两个以外的以下其他
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'course',
'USER': 'root', #用户名
'PASSWORD': '0000', #密码
'HOST': '127.0.0.1',
'PORT': 3306
}
}
2.去创建 数据库名为: course 的数据库
字符集为: utf8mb4 -- UTF-8 Unicode
排序规则为: utf8mb4_general_ci
python manage.py check django校验
#生成迁移文件
python manage.py makemigrations #数据库语句生成
#数据表映射到数据库当中
python ./manage.py migrate #数据库同步
数据库表名更改
models.py 模型类里加 :
class Meta:
db_table = 'teacher'(想要更改的名字)
Django可视化 (把英文变成中文)
在setting中找到LANGUAGE_CODE,TIME_ZONE,USE_TZ改为以下
#改为中文:zh-Hans(中文)
LANGUAGE_CODE = 'zh-Hans'
#使用的时间:亚洲/上海(不要使用北京)
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
#****创建管理员****#
1.python manage.py createsuperuser 或者在 pychar中顶部找到Tools runmanage,py点击进入输入createsuperuser
2.在页面打开网址 http://127.0.0.1:8000/admin 回车 进行Django管理员登录
##***不想在输入 python manage.py命令 可以弄以下操作****##
pychar中顶部找到Tools runmanage,py点击进入
注册模型到Djano管理页面(admin.py)且改为中文视图
1.courses项目下的migrations下的admin.py里导入想要注册的模型 from .models import Teacher, Course, Student, TeacherAssistant
2.开始注册模型: (把自定义的模型注册到Django的admin当中)
from django.contrib import admin
from .models import Teacher, Course, Student, TeacherAssistant
admin.site.register(Teacher)
admin.site.register(Course)
admin.site.register(Student)
admin.site.register(TeacherAssistant)
3.刷新页面网址 http://127.0.0.1:8000/admin
4. 注册内容改为中文
models.py 模型类里加 :
class Meta:
//这行是改数据库表名 db_table = 'teacher'(数据库表想要更改的名字)
verbose_name = '讲师信息表' (网页页面想要更改的名字)
# 不管单数复数都显示"讲师信息表"这个内容
verbose_name_plural = verbose_name
5.admin页面 应用名字改为中文:
models.py 模型类里加 : verbose_name = "课程管理"(要改的名字)
6.admin页面模型内容添加后返回正常可视化结果:
models.py中每个模型类加上返回值:
def __str__(self):#添加后返回一个可视化结果
return self.nickname
定义视图函数,设置路由 (返回字符串)
1.views:视图层(浏览器发送的请求会先来到视图层)
# HttpResponse:返回字符串:
from django.http import HttpResponse, JsonResponse
def index(request):
return HttpResponse('hello Django')
2.去到项目(zhonghui)的urls.py定义路由 (项目url复制转发作用) (分发作用)
# include需要导入,应用(courses)下的urls没有需要创建, #namespace:命名空间,一个项目可能有很多应用,
# courses浏览器上输入的地址 视图函数名字可能一样,由命名空间去找对应的视图函数
from django.urls import path, include, re_path
path('courses/', include('courses.urls', namespace='courses')),
*************************************************************************************************************************
### 配置首页路由每次 直接跳转到: http://127.0.0.1:8000/courses/index/
#导入应用courses 的views文件
from courses import views #直接跳转到应用(courses)的views文件下的index函数
re_path(r'^$', views.index) # r:路由, ^:正则表达式,表示开始, ^$:没有开始的东西也没有结束的东西
*************************************************************************************************************************
3.去到应用(courses)的刚刚创建出的urls.py定义路由(子路由): (配置路由作用)
from django.urls import path
from . import views
#给应用起一个名字
app_name = 'courses'
urlpatterns = [
path('index/', views.index, name='index')
# path(定义的视图函数名字,用这个路由要访问的视图函数(需导入),给这个路由起个名字,后面要反向生成某个url地址要用到)
]
4.再访问这个地址:http://127.0.0.1:8000/courses/index/ 就能看到结果
[扩展:
from django.urls import path
from . import views
1.#反向生成首页的url地址(要用到首页的URL,又不能用字符串写死)
视图层(views,py)下:
from django.urls import reverse
def index(request):
#reverse('传入要生成url的视图函数的名字(命名空间)')
print(reverse('courses:index')) #在终端打印出url
return HttpResponse('ok')
应用(courses)下的urls.py中:
urlpatterns = [
path('index/', views.index, name='index') #示例/course/index (/项目url/跳转到的应用路由名字)
]
再访问这个地址:http://127.0.0.1:8000/courses/index/ 就能看到结果
2.传参:
1.获取http://127.0.0.1:8000/courses/index/2的形势:
改应用的url,因为项目url只负责转发,
#index/<int:v>中<int:v>:要接收的数据类型
path('index/<int:v>', views.index, name='index')
改视图函数(views.py)中:
def index(request, v):#(方法一)
return HttpResponse(f'接收到的参数是: {v}')
再访问这个地址:http://127.0.0.1:8000/courses/index/2 就能看到结果
2.获取https://127.0.0.1:8000/courses/index?age=20&name=lisa的形势:
(一般用get) get方式:直接账号密码/参数放在路由当中 ; post方式:账号密码放在请求头当中 .
def index(request):#(方法二)
if request.method == 'GET':
name = request.GET.get('name', '')
age = request.GET.get('age', 0)
#给网页回复字符串
return HttpResponse(f'接收到的参数是: {name}-{age}') #返回字符串
#给网页回复josn字符串,返回字典
return JsonResponse({'name': name, 'age': age}) #字典的形势返回
应用的url为:
path('index/', views.index, name='index')
再访问这个地址:http://127.0.0.1:8000/courses/index?age=20&name=lisa 就能看到结果
3.增删改查
(要导入相应的数据:from .models import Teacher, Course, Student
全都是再访问这个地址: http://127.0.0.1:8000/courses/index/ 就能看到结果)
# def index(request): #查询索引 all返回的是QuerySet对象
# teachers = Teacher.objects.all() #查找数据里的所有数据
# teacher = Teacher.objects.all()[:1] #切片方式 只拿一个老师
# print(teachers, teacher)
# query:查询相应的数据库查询语句
# print(teachers.query)
# print(teacher.query)
# return HttpResponse('ok')
# def index(request): #通过名字查找 ,使用get方法会直接执行sql语句获取数据
# teacher = Teacher.objects.get(nickname='lisa') #get老师名字拿到老师 模型对象 不能遍历
# print(teacher)
# print(type(teacher)) #查询类型
# return HttpResponse('ok')
--------------------------------------------------------------------------------------------------------------------------------
get和filter
| get:是从数据库取得满足筛选条件的对象,但如果此时数据库有多个满足条件的值,或者没有满足筛选条件的值,都会报错。
|
| 比如:p=User.objects.get(username='answer'),
|
| 此时数据库必须只有一个满足条件的对象,不然会报错。
|
| 返回的对象可以用p.__dict__来查看,它是以字典的形式返回的,{'key':valeus},key是字段的名称,而values是值的内容。
|
| filter:filter方法是从数据库取得所有匹配的结果,返回一个对象列表,如果记录不存在的话,它会返回[]。
|
|
| 比如我数据库里有一条记录(或多条),记录的name的值是answer的话,我用p = User.objects.filter(name='answer')
| 它返回的student是一个对象的列表,而student[0]和上面的get方式返回的student的结果是一样的。
|
| 另外我从别的资料里看到filter好像有缓存数据的功能,第一次查询数据库并生成缓存,下次再调用filter方法的话,直接取得缓存的数据,
| 而get方法每次执行都是直接查询数据库的,不知道这个是不是正确。
---------------------------------------------------------------------------------------------------------------------------------
#django的filter方法是从数据库的取得匹配的结果,返回一个对象列表,如果记录不存在的话,它会返回[]
# def index(request): #过滤 filter
# teachers = Teacher.objects.filter(fans__gte=20000) #fans__gte:大于等于
# print(type(teachers))
# print(teachers)
# return HttpResponse('ok')
# def index(request): #排序 order_by
# teachers = Teacher.objects.all().order_by('-fans') #fans:从小到大 -fans:从大到小
# print(type(teachers))
# print(teachers)
# return HttpResponse('ok')
# def index(request): #关联关系查询 一对多 select_related
# courses = Course.objects.all().select_related('teacher')
# for course in courses:
# print(course.title, course.teacher.nickname)
#
# return HttpResponse('ok')
# def index(request): #关联关系查询 多对多 prefetch_related
# students = Student.objects.all().prefetch_related('course')
# for s in students:
# print(s.course.all())
#
# return HttpResponse('ok')
# def index(request): #反向查询 查询名字为lisa老师的所有课程
# courses = Teacher.objects.get(nickname='lisa').course_set.all()
# print(courses)
# return HttpResponse('ok')
# def index(request): #添加/实例化一个对象 save方法
# teacher = Teacher()
# teacher.nickname = '李思'
# teacher.introduction = '自我介绍'
# teacher.fans = 1000
# teacher.save()
# return HttpResponse('ok')
# def index(request): #添加/实例化一个对象 create方法
# Teacher.objects.create(
# nickname='小颜',
# introduction='嘿嘿',
# fans=2000
# )
# return HttpResponse('ok')
# def index(request): #更新/修改 update
# Teacher.objects.filter(nickname='李思').update(
# introduction='嘿嘿',
# fans=2000
# )
# return HttpResponse('ok')
# def index(request): #删除delete
# Teacher.objects.filter(nickname='李思').delete()
# return HttpResponse('ok')
]
1、MVC
MVC模式就是把web应用分为模型(M),控制器©,视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。
M:model 模型(django中models.py文件),与数据库进行交互。
V: view 视图(django中templates目录),产生html页面。
C:controller 控制器(django中urls.py和views.py文件),接收请求,做业务逻辑判断进行处理,与M和V进行交互,返回响应。
2、MTV
Django的MTV模式本质上与MVC模式没有什么差别,也是各组件之间为了保持松耦合关系,只是定义上有些许不同,Django的MTV分别代表:
Model(模型):负责与数据库进行交互。
Template(模版):产生html页面。
View(视图):负责业务逻辑,并在适当的时候调用Model和Template,做出逻辑判断返回响应。
制作视图页面(返回html页面,而不是单纯返回字符串)
1. 模板文件的创建与配置: (templates) 导入:import os.path
1.在项目下创建一个文件用来装模板(templates)
2. 创建模板文件后 右键模板文件找到Mark Directory as 再找到Template Folder
3.去到settings.py里找到TEMPLATES下面的'DIRS'里补充你的模板放在哪一个目录(路径)下面
因为上面的BASE_DIR里帮获取到了路径(BASE_DIR = Path(__file__).resolve().parent.parent),
所以就需要进行拼接: os.path.join(BASE_DIR, 'templates')
再放进去 : 'DIRS': [os.path.join(BASE_DIR, 'templates')] 就行了
4.把原先弄好的html页面复制进templates
2. 静态文件的创建与配置:(static) 导入:import os.path
1.在项目下创建一个静态文件,用来放css,图片
2.去到settings.py里找到STATIC_URL = '/static/',
3.在其下面自己定义一个
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
4.因为上面的BASE_DIR里帮获取到了路径,所以就需要进行拼接: os.path.join(BASE_DIR, 'static')
5.把原先弄好的html页面所需要的css,img复制进static
3.去视图函数(views.py)里定义一个index返回html文件
def index(request):
teachers = Teacher.objects.all() #通过'teachers'这个键显示到html页面
return render(request, 'course.html', {'teachers': teachers})
*********************************************************************************************************************
4.去项目(zhonghui)url中的urlpatterns下配置首页路由(为了不每次访问首页都要在输入栏打上很长的地址 )
### 配置首页路由每次 直接跳转到: http://127.0.0.1:8000/courses/index/
#导入应用courses 的views文件
from courses import views #直接跳转到应用(courses)的views文件下的index函数
re_path(r'^$', views.index) # r:路由, ^:正则表达式,表示开始, ^$:没有开始的东西也没有结束的东西
*********************************************************************************************************************
5.首页的html页面显示数据库里techers的所有老师
1.把原先弄好的html页面(course.html)复制进templates,把原先弄好的html页面所需要的css,img复制进static
2.视图函数(views.py)里定义一个的index里加上:teachers = Teacher.objects.all()
def index(request):
teachers = Teacher.objects.all() #通过'teachers'这个键显示到html页面
return render(request, 'course.html', {'teachers': teachers})
3.html页面中运用for循环接受视图函数通过teachers键传过来的数据
看好html页面布局,弄出: {% %}:页面中执行这里面的代码; {{ }}页面中显示这里面的内容
{% for teacher in teachers %}
<tr>
<!-- <td style="width: 80px">1</td>-->
<td style="width: 100px">{{ teacher.nickname }}</td>
<td style="width: 600px;text-align: left;text-indent: 2px;">{{ teacher.introduction }}</td>
<td style="width: 100px;">{{ teacher.fans }}</td>
<td>
<a href="{% url 'courses:update' teacher.nickname %}">
<button type="button" class="btn btn-primary ">修改</button>
</a>
<a href="{% url 'courses:delete' teacher.nickname%}">
<button type="button" class="btn btn-primary ">删除</button>
</a>
</td>
</tr>
{% endfor %}
6.(添加)首页的html上点击添加信息跳转到另一个页面进行添加信息
(老操作 导入html以及相关css,img, 配置应用路由去到视图层, 在添加视图函数(views.py)用于从模型层去取数据库数据)
1.把原先弄好的html页面(add.html)复制进templates,把原先弄好的html页面所需要的css,img复制进static
2.在应用的url里新添路由path('add/', views.create, name='create'),
3.在视图函数(views.py)中添加 create类 用于从模型层去取数据库数据:
def create(request):
#接收页面提交过来的数据
#因为add,html应用form表单post方式进行提交数据,所以要判断是'GET'还是'POST'
if request.method == 'POST':
# 接收页面提交过来的数据:括号里的'nickname'是html页面输入框中的name
nickname = request.POST.get('nickname', '')
introduce = request.POST.get('introduce', '')
fans = request.POST.get('fans', 0)
# 添加/储存 : save方法实例化一个对象
teacher = Teacher()
teacher.nickname = nickname
teacher.introduction = introduce
teacher.fans = int(fans)
teacher.save()
#添加完成后跳转到某页面 redirect
return redirect('courses:index')
return render(request, 'add.html')
4.在add.html页面中调试好form表单中要提交到页面的地址
#action:要提交到的页面; method:提交方式
<form action="{% url 'courses:create' %}" method="post">
5.在首页(course.html)中调好添加信息按钮的href:
#href:要跳转的页面 {% %}:页面中执行这里面的代码 # path('add/', views.create, name='create'),
# url 'courses:create' : url地址, courses是应用url里自建的名字, create是应用url里定义的路由名
****也可以写成 href="/courses/add/"****
<a href="{% url 'courses:create' %}">
<button type="button" class="btn btn-primary table_b">添加信息</button>
</a>
7.(修改)首页的html上点击修改进行修改此条信息:
1.把原先弄好的html页面(add.html)复制进templates,把原先弄好的html页面所需要的css,img复制进static
2.应用url里添加路由:
#<str:name>页面传过来的名字
path('update/<str:name>', views.update, name='update'),
3. 在视图函数(views.py)中添加 update类 用于从模型层去取数据库数据:
#以查询老师的名字来进行修改,用name接受页面中传过来的teacher.nickname
def update(request, name):
#因为页面中href写的是路径地址,是从地址栏传输过来的数据,所以用GET接收
if request.method == "GET":
#查询数据库中nickname为传过来的name的teacher
teacher = Teacher.objects.filter(nickname=name)
#以'teacher'键传输查询到的teacher(QuerySet对象)中的第0条数据给ypdata.html
return render(request, 'update.html', {'teacher': teacher[0]})
#获取update.html修改页面传过来的数据
if request.method == 'POST':
introduce = request.POST.get('introduce', '')
fans = request.POST.get('fans', 0)
#拿过来的数据修改到数据库
Teacher.objects.filter(nickname=name).update(
introduction=introduce,
fans=fans
)
#redirect:跳转
return redirect(reverse('courses:index'))
4.在update.html页面中调试
#action:要提交到的页面; method:提交方式
<form action="/courses/update/{{ teacher.nickname }}" method="post">
5.在首页(course.html)中调好修改按钮的href:
#href:要跳转的页面 {% %}:页面中执行这里面的代码 # path('add/', views.create, name='create'),
# url 'courses:update' : url地址, courses是应用url里自建的名字, update是应用url里定义的路由名
***path('update/<str:name>', views.update, name='update'),***
***:update' teacher.nickname=/update/{{ teacher.nickname }}***
<a href="{% url 'courses:update' teacher.nickname %}">
8.(修改)首页的html上点击删除进行删除此条信息:
1.应用url里添加路由:
#<str:name>页面传过来的名字
path('delete/<str:name>', views.delete, name='delete'),
2. 在视图函数(views.py)中添加 delete类 用于从模型层去取数据库数据:
def delete(request, name):
#因为是url当中传过来的name,能保证传过来的名字一定有除非是用户自己在地址栏输入的
***使用这个get查询不到会报错,使用filter查询不到会返回一个空***
Teacher.objects.get(nickname=name).delete()
return redirect(reverse('courses:index'))
3.在首页(course.html)中调好删除按钮的href:
<a href="{% url 'courses:delete' teacher.nickname%}">
[扩展
https://127.0.0.1:8000/courses/index
*courses:是(zhonghui)下的url中
(path('courses/', include('courses.urls', namespace='courses')),)的:'courses/'部分
由include('courses.urls')转发给应用中的url('courses.urls')
*index:是应用中的url下的
(path('index/', views.index, name='index'),)中的'index/'
**.页面中的css样式转去static里的时候:
页面顶部加:{% load static %}
页面中(style里)加: <style>
@import url('/static/css/course.css');
</style>
“./”:代表目前所在的目录
“. ./”:代表上一层目录
“/”:代表根目录
]
{% load static %}
@import url('/static/css/course.css');
background: url("./static/img/cour.png");
background: url("./static/img/hh.jpg");
{% csrf_token %}
{% for teacher in teachers %}
{% endfor %}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构