一、安装django
pip install django
这里我使用的是Django 3.2.6
二、创建项目
移动到相应的路径,在终端执行以下指令,会创建一些默认的文件和默认的文件夹:
django-admin startproject demosite
让我们看看 startproject 创建了些什么:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
这些目录和文件的用处是:
-
最外层的 mysite/ 根目录只是你项目的容器, 根目录名称对 Django 没有影响,你可以将它重命名为任何你喜欢的名称。 -
manage.py : 一个让你用各种方式管理 Django 项目的命令行工具。你可以阅读 django-admin 和 manage.py 获取所有 manage.py 的细节。 -
里面一层的 mysite/ 目录包含你的项目,它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如 mysite.urls ). -
mysite/__init__.py :一个空文件,告诉 Python 这个目录应该被认为是一个 Python 包。如果你是 Python 初学者,阅读官方文档中的 更多关于包的知识。 -
mysite/settings.py :Django 项目的配置文件。如果你想知道这个文件是如何工作的,请查看 Django 配置 了解细节。 -
mysite/urls.py :Django 项目的 URL 声明,就像你网站的“目录”。阅读 URL调度器 文档来获取更多关于 URL 的内容。 -
mysite/asgi.py :作为你的项目的运行在 ASGI 兼容的 Web 服务器上的入口。阅读 如何使用 ASGI 来部署 了解更多细节。 -
mysite/wsgi.py :作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。阅读 如何使用 WSGI 进行部署 了解更多细节。
简而言之:
默认项目的文件介绍
mysite
├── manage.py 【项目的管理,启动项目、创建app、数据管理】【不要动】【***常常用***】
└── mysite
├── __init__.py
├── settings.py 【项目配置】 【***常常修改***】
├── urls.py 【URL和函数的对应关系】【***常常修改***】
├── asgi.py 【接收网络请求】【不要动】
└── wsgi.py 【接收网络请求】【不要动】
特殊说明:
创建Django项目实际上有两种方式
三、创建app
python manage.py startapp app01
文件说明:
- 项目
- app,用户管理【表结构、函数、HTML模板、CSS】
- app,订单管理【表结构、函数、HTML模板、CSS】
- app,后台管理【表结构、函数、HTML模板、CSS】
- app,网站 【表结构、函数、HTML模板、CSS】
- app,API 【表结构、函数、HTML模板、CSS】
..
注意:我们开发比较简洁,用不到多app,一般情况下,项目下创建1个app即可。
├── app01
│ ├── __init__.py
│ ├── admin.py 【固定,不用动】django默认提供了admin后台管理。
│ ├── apps.py 【固定,不用动】app启动类
│ ├── migrations 【固定,不用动】数据库变更记录
│ │ └── __init__.py
│ ├── models.py 【**重要**】,对数据库操作。
│ ├── tests.py 【固定,不用动】单元测试
│ └── views.py 【**重要**】,函数。
├── manage.py
└── mysite2
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py 【URL->函数】
└── wsgi.py
四、快速上手
4.1、快速体验
- 注册app(settings.py)
- 编写URL与视图函数的对应关系(urls.py)
- 编写视图函数(views.py)
- 启动django项目
(1)之前我们创建了app,使用前先注册
将之添加入settings.py
(2)编写URL与视图函数的对应关系(urls.py)
settings.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', views.index),
]
(3)编写视图函数(views.py)
app01/views.py
from django.shortcuts import render, HttpResponse
def index(request):
return HttpResponse("Hello World")
(4)启动django项目
两种方法:
-
命令行模式 python manage.py runserver
-
PyCharm打开 (如果该项目是由PyCharm创建的,左上角会有个开始按钮)
127.0.0.1:8000/admin/
注意别访问成了:http://127.0.0.1:8000/
提示你我们只创建了 127.0.0.1:8000/admin/
4.2、templates模板
4.1中我们返回了一个”Hello World“,那么如何返回一个HTML文件呢?
(1)创建HTML文件
在app01下创建目录templates,里面存放HTML文件
user_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<h1> hello </h1>
{# <img src="/static/img/1.jpg" alt="">#}
</body>
</html>
(2)编写函数
demosite/app01/views.py
from django.shortcuts import render, HttpResponse
def index(request):
return HttpResponse("Hello World")
def user_list(request):
"""
关于user_list.html的查找:
1、优先去主目录下的templates查找
2、根据app的注册顺序,逐一去每个app下的templates下查找
"""
return render(request, "user_list.html")
(3)效果展示
4.3、静态文件
开发中,一般将
做静态文件
(1)存放格式
引用静态文件两种方法:
1、直接用路径就好了
2、修改配置文件(推荐)
(2)引入jquery与bootstrap
(1)找网址
jQuery官网经常打不开,这里提供一个网址::jQuery
找到要下载的版本,点击下载
(2)百度网盘
- 链接:https://pan.baidu.com/s/1QmzgWtihzr1CH6zUV2CmNA
提取码:1234
五、Django模板语法
5.1、示例效果
views.py
def tql(request):
name = "DLNovice"
return render(request, "tql.html", {"n1": name})
tql.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Coder</title>
</head>
<body>
<h1> 模板语法的学习 </h1>
<div>{{ n1 }}</div>
</body>
</html>
演示:
更多变量类型,如字典,参考菜鸟教程:Django 模板 | 菜鸟教程 (runoob.com)
5.2、概念
本质上:在HTML中写一些占位符,由数据对这些占位符进行替换和处理。
5.3、案例:伪联通新闻中心
六、请求和响应
6.1、三个请求与三个响应
三个请求与三个响应
关于重定向:
6.2、案例:用户登录
我们做个简单案例,输入账号密码,返回“登录成功”
urls.py
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path("login/", views.login),
]
app01/views.py
from django.shortcuts import render, HttpResponse
def login(request):
if request.method == "GET":
return render(request, "login.html")
else:
return HttpResponse("登录成功")
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<h1> 用户登录 </h1>
<form method="post" action="/login/">
<input type="text" name="user" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<input type="submit" value="提交">
</form>
</body>
</html>
但是你发现,你随便输入数据后提交,报错:
其实这个用flask就不会报这个错,但django不行
因为django多了一个机制,你可以理解为多了一层安全机制的效验
解决方案:
在form表单里添加一句:
{% csrf_token %}
重启项目后,输入账号密码并提交:
加点细节
- 设置账号密码验证(后文中再引入数据库)
- 账号密码正确:重定向,跳转到其他页面
- 账号密码错误:提示“账号或密码错误”
views.py
from django.shortcuts import render, HttpResponse, redirect
def login(request):
if request.method == "GET":
return render(request, "login.html")
else:
username = request.POST.get("user")
password = request.POST.get("password")
if username == "root" and password == "123":
return redirect("https://www.csdn.net/")
else:
return render(request, "login.html", {"error_msg": "用户名或密码错误"})
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<h1> 用户登录 </h1>
<form method="post" action="/login/">
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<input type="submit" value="提交"/>
<span style="color: red;">{{ error_msg }}</span>
</form>
</body>
</html>
效果演示:
七、数据库操作
下面我们使用ORM框架
7.1、安装第三方仓库
pip install mysqlclient
如果安装失败,百度搜索“mysqlclient wheel”,我们直接下载安装包
mysqlclient · PyPI
7.2、ORM
ORM可以帮我们做两件事:
1、创建数据库
启动mysql
[root@host]
Enter password:******
创建数据库
mysql> create database 数据库名字;
Query OK, 1 row affected (0.01 sec)
2、django连接数据库
在settings.py文件中进行配置和修改。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dj',
'USER': 'root',
'PASSWORD': 'xxx',
'HOST': '127.0.0.1',
'PORT': 3306,
}
}
django默认用的数据库是sqlite,现在我们改用mysql
3、django操作表
修改app下的models.py
如:
from django.db import models
class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
age = models.IntegerField()
执行俩命令:
(前提:app已注册)
python manage.py makemigrations
python manage.py migrate
我们查看一下数据库
- 进入数据库
use 数据库名字; show tables; desc 表的名字;
show tabes可以看到生成了一堆表,为啥呢?
- 我们在settings.py中可以看到django默认注册了许多app,他们依赖许多表
那么我们又想添加表了,或者哪个表不想要了怎么办呢?
更改app下的models.py
-
添加表就直接加代码,删除表或删除表中的某个元素就注释掉相应的代码 -
每次修改代码,都重新运行一下那俩命令 python manage.py makemigrations
python manage.py migrate
但是,如果表已存在,它里面很有可能是有数据的,这时候你去修改表,就像一个excel表格,你突然要添加一个列。
这时,运行python manage.py makemigrations 时就会给你俩选择:
>>> python manage.py makemigrations
You are trying to add a non-nullable field 'phone' to userinfo without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
- 手动填充
- 退出
或者,你在代码里添加默认值(default),如:age = models.IntegerField(default=18)
4、操作表中数据
常用的四大操作:增删改查
(1)添加数据
我们在views.py添加一个函数orm()
from django.shortcuts import render, HttpResponse, redirect
from app01.models import Department, UserInfo
def orm(request):
Department.objects.create(title="销售部")
Department.objects.create(title="运营部")
Department.objects.create(title="IT部")
return HttpResponse("数据添加成功")
- 然后运行项目
python manage.py runserver - 并访问 http://127.0.0.1:8000/orm
这时我们查一下数据库:
但注意不要重复添加,已添加的数据就注释了
否则就会这样。。。。。
对于需要参数的表,如我们之前设置的UserInfo():
我们修改一下函数
def orm(request):
UserInfo.objects.create(name="coder01", password="01", age="18")
UserInfo.objects.create(name="coder02", password="02", age="19")
UserInfo.objects.create(name="coder03", password="03", age="20")
return HttpResponse("数据添加成功")
- 我们重新访问 http://127.0.0.1:8000/orm
- 查看数据库,可以看到
(2)删除数据
def orm(request):
Department.objects.all().delete()
UserInfo.objects.filter(id=3).delete()
return HttpResponse("数据删除成功")
(3)获取数据
def orm(request):
data_list = UserInfo.objects.all()
for obj in data_list:
print(obj.id, obj.name, obj.password, obj.age)
first = UserInfo.objects.filter(id=1).first()
print(first.name, first.password)
return HttpResponse("数据获取成功")
可以在终端看到:
System check identified no issues (0 silenced).
February 14, 2022 - 20:48:51
Django version 3.2.6, using settings 'demosite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
1 coder01 01 18
2 coder02 02 19
coder01 01
[14/Feb/2022 20:48:55] "GET /orm/ HTTP/1.1" 200 18
(4)修改数据
def orm(request):
UserInfo.objects.filter(name="coder02").update(age=22)
return HttpResponse("数据修改成功")
7.3、案例:用户管理
1、展示用户列表
views.py
def info_list(request):
data_list = UserInfo.objects.all()
return render(request, "infolist.html", {"data_list": data_list})
infolist.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<h1> 用户列表 </h1>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>密码</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
{% for obj in data_list %}
<tr>
<th>{{ obj.id }}</th>
<th>{{ obj.name }}</th>
<th>{{ obj.password }}</th>
<th>{{ obj.age }}</th>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
2、添加用户
urls.py
path("info/add/", views.info_add)
views.py
from django.shortcuts import render, HttpResponse, redirect
from app01.models import Department, UserInfo
def info_add(request):
if request.method == "GET":
return render(request, "info_add.html")
user = request.POST.get("user")
password = request.POST.get("pwd")
age = request.POST.get("age")
UserInfo.objects.create(name=user, password=password, age=age)
return redirect("http://127.0.0.1:8000/infolist/")
info_add.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户注册</title>
</head>
<body>
<h1>用户注册</h1>
<form method="post", action="/info/add/">
{% csrf_token %} {#不要忘了添加这一句:避免django的那层安全机制的效验#}
<input type="text" name="user" placeholder="用户名">
<input type="text" name="pwd" placeholder="密码">
<input type="text" name="age" placeholder="年龄">
<input type="submit" value="注册">
</form>
</body>
</html>
然后就直接跳转到我们之前写的:查看用户列表功能
小优化:添加跳转功能
我们希望在
用户列表那可以添加按钮”用户注册“,直接跳转到用户注册界面
==》 在展示用户列表的那个HTML文件里加个标签就好了
<a href="http://127.0.0.1:8000/info/add/">用户注册</a>
3、删除用户
我们现在实现一个功能,通过访问url的方式删除用户
将要删除的用户标记在url中
比如:
访问 http://127.0.0.1:8000/info/delete/?nid=1
就删除id=1的用户
效果展示如下:
我们将这个删除用户的功能添加到”展示用户列表“模块
urls.py
path("info/delete/", views.info_delete),
views.py
def info_delete(request):
nid = request.GET.get("nid")
UserInfo.objects.filter(id=nid).delete()
return redirect("/infolist/")
infolist.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<h1> 用户列表 </h1>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>密码</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for obj in data_list %}
<tr>
<th>{{ obj.id }}</th>
<th>{{ obj.name }}</th>
<th>{{ obj.password }}</th>
<th>{{ obj.age }}</th>
<th>
<a href="http://127.0.0.1:8000/info/delete/?nid={{ obj.id }}">删除</a>
</th>
</tr>
{% endfor %}
</tbody>
</table>
<a href="http://127.0.0.1:8000/info/add/">用户注册</a>
</body>
</html>
|