Nice to meet you, Django
django
的安装和基本使用
pip install django
但是这样安装的应该是最新版的,想用其他版本的在Django
后加版本号
创建django项目和APP
django-admin startproject blogsy
创建一个blogsy
项目
bolgsy/ # 最外层的 blogsy/ 根目录只是你项目的容器,根目录名称对`Django`没有影响,可以将它重命名 manage.py # 一个让你用各种方式管理 Django 项目的命令行工具 blogsy/ # 它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如 mysite.urls). __init__.py # 一个空文件,告诉Python这个目录应该被认为是一个Python包。 settings.py # Django项目的配置文件。 urls.py # Django项目的URL声明,就像你网站的“目录”。 asgi.py # 作为你的项目的运行在ASGI兼容的Web服务器上的入口。 wsgi.py # 作为你的项目的运行在WSGI兼容的Web服务器上的入口。
django-admin startapp blog
创建一个blog
APP
blog/ __init__.py admin.py apps.py migrations/ __init__.py models.py tests.py views.py 创建app后,需要去django项目配置文件中,也就是setting.py文件中的 # Application definition 1 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog.apps.BlogConfig' # 注册创建的APP,这里应该是APP的一个类,可以在apps.py文件中看到 'blog' # 应该也可以直接写APP的名称,没测试,我还不知道行不行 ]
项目和
APP
的区别
- 一个项目下可以有多个
APP
Django
常用指令
django-admin startproject csdn
创建csdn
项目python manage.py startapp edu
或python diango-admin.py startapp blog 创建edu或者blog APP
,还有上面的那个python manage.py creatsuperuser
创建超级管理员python manage.py changepassword weiwei
更改用户weiwei
的密码python manage.py makemigrations
同步数据库python manage.py migrate
同步(迁移)数据库python manage.py flush
清空数据库python manage.py shell
进行交互式控制python manage.py runserver
运行项目(默认端口8000)python manage.py runserver 85
指定端口85运行项目python manage.py runserver 0:8000
为了监听所有服务器的公开IP(这你运行 Vagrant 或想要向网络上的其它电脑展示你的成果时很有用)
urls.py
和views.py
文件
编写web试图最常用的两个文件,可以说也就是这两个文件
urls.py
from django.contrib import admin
from django.urls import path
from blog import views
urlpatterns = [
# path('admin/', admin.site.urls),
# 正如上面所说这是Django项目的URL声明,就像你网站的“目录”。
path('index/', views.index),
path('html1/', views.htmltest1),
path('html2/', views.htmltest2),
path('login/', views.login),
]
path的参数说明:
函数 path()
具有四个参数,两个必须参数:route
和 view
,两个可选参数:kwargs
和 name
。
path()
参数:route
route
是一个匹配 URL 的准则(类似正则表达式)。当Django
响应一个请求时,它会从urlpatterns
的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项。这些准则不会匹配 GET 和 POST 参数或域名。例如,
URLconf
在处理请求https://www.example.com/myapp/
时,它会尝试匹配myapp/
。处理请求https://www.example.com/myapp/?page=3
时,也只会尝试匹配myapp/
。
path()
参数:view
当
Django
找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个HttpRequest
对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。
path()
参数:kwargs
任意个关键字参数可以作为一个字典传递给目标视图函数。本教程中不会使用这一特性。
path()
参数:name
为你的
URL
取名能使你在Django
的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个URL
模式。
views.py
# 别忘了导入这些函数
from django.shortcuts import render,HttpResponse,redirect
# Create your views here.
def index(request):
return HttpResponse("欢迎使用")
# 1. 优先去项目根目录的templates中寻找
# 2. 根据APP的注册顺序,在每个APP下的templates寻找html文件
def htmltest1(request):
return render(request,"htmltest1.html")
def htmltest2(request):
# 重定响
# 当用户访问htmltest2页面时,直接跳转到链接 https://www.baidu.com
return redirect("https://www.baidu.com")
def login(request):
if request.method == "GET" :
return render(request,"login.html")
else:
# 如果是POST的请求,获取用户提交的数据
print(request.POST)
return HttpResponse("登陆成功")
模板语法与静态文件
静态文件
一般静态文件会放在APP
(blog
)下的static
目录中,比如图片(imgs
)、css
、js
、插件(plugins
)等等
html
文件一般放在APP
下的templates
目录下
模板语法
django
提供的自己特有的模板语法,然后再对其进行渲染!
例:
# 在views.py文件中定义一`tpl(template)函数
def tpl(request):
name = "yanghe"
roles = ["管理员", "CEO", "保安"]
user_info = {"name":"郭智", "age":10, "sex":"男", "major":"computer"}
user_list = [
{"name":"郭智", "age":10, "sex":"男", "major":"computer"},
{"name":"郭智", "age":10, "sex":"男", "major":"computer"},
{"name":"郭智", "age":10, "sex":"男", "major":"computer"}
]
return render(request, 'tpl.html', {"n1":name, "n2":roles, "n3":user_info, "n4":user_list})
<!-- html文件中的模板语法写法 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>htmltest1</title>
</head>
<body>
<h1>html测试1</h1>
<img src="" alt="">
<!-- 访问name单个属性可以这样写 -->
<div>{{ n1 }}</div>
<!-- 访问列表 -->
<div>{{ n2 }}</div>
<!-- 这样就直接输出的是原生列表也就是roles = ["管理员", "CEO", "保安"] -->
<!-- 取列表的某个值 -->
<div>{{ n2.0 }}</div>
<!-- 管理员 -->
<div>{{ n2.1 }}</div>
<div>{{ n2.2 }}</div>
<!-- 循环n2 -->
<div>
{% for item in n2 %}
<span>{{ item }}</span>
{% endfor %}
</div>
<!-- 横线 -->
<hr/>
<!-- 访问字典 -->
<!-- 同样也是直接输出原生字典 {"name":"郭智", "age":10, "sex":"男", "major":"computer"} -->
<div>{{ n3 }}</div>
<!-- 访问键值 -->
{{ n3.name }}
<!-- 循环n3 访问键值对-->
<ul>
{% for k,v in n3.item %}
<li>{{ k }}={{ v }}</li>
{% endfor %}
</ul>
<!-- 访问列表里的字典 -->
<hr/>
{{ n4.1 }}
{{ n4.1.name }}
<!-- 循环这个列表 -->
{% for item in n4 %}
<li>{{ item.name }} {{ item.age }}</li>
{% endfor %}
<!-- 条件语句 -->
{% if n1 == "yanghe" %}
<h1>dadadadadada</h1>
{% elif n1 == "xxx" %}
<h1>bibi</h1>
{% else %}
<h1>dudududududu</h1>
{% endif %}
</body>
</html>
请求与响应
get和post的区别:
html
中<form>
表单的属性:
属性 | 描述 |
---|---|
accept-charset | 规定用于表单提交的字符编码。 |
action | 规定提交表单时将表单数据发送到何处。 |
autocomplete | 规定表单是否应打开自动完成(填写)功能。 |
enctype | 规定将表单数据提交到服务器时应如何编码(仅供 method=“post”)。 |
method | 规定发送表单数据时要使用的 HTTP 方法。 |
name | 规定表单名称。 |
novalidate | 规定提交时不应验证表单。 |
rel | 规定链接资源和当前文档之间的关系。 |
target | 规定提交表单后在何处显示接收到的响应。 |
例:
<form method="post" action="/login/">
<!-- django中独有的安全验证,不写下面这行,可能执行不了“真正的提交” -->
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="password" name="psw" placeholder="密码">
<input type="submit" value="提交"/>
</form>
mysql的连接与应用
ORM框架
ORM通俗的理解就是django将数据库的一些操作进行再封装,通过django提供的特有的数据库操作语法,实现对数据库中的表进行创建和管理的功能。
注意:
它只能创建数据库中的表!不能创建数据库!创建数据库使用:create database 数据库名 charset=“utf8”
项目与mysql的连接
链接前的一些准备(配置!)
# 先安装 mysqlclient 第三方模块
pip3 install mysqlclient
"""
mysqlclient 安装总是一堆错误,暂时还没有搞懂,有时间再搞吧,用pymysql
"""
# 安装pymysql
pip install pymysql
# 安装mysqlclient或者pymysql的时候,前提是你有mysql
# apt-get install mysql-server # 安装数据库
# sudo systemctl status mysql # 查看数据库是否正常运行
# sudo mysql_secure_installation # 设置密码和数据库的安全性
# 此时你应该是给root用户创建了你的数据库密码,比如是123456
# 安装完pymsql后需要在blogsy下的__init__.py文件中导入pymysql
import pymysql
pymysql.install_as_MySQLdb() # 设置数据库连接模块
# 打开blodsy下的settings.py进行数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',#选择的数据库引擎mysql
'NAME': 'django_db', # 自己创建的数据库,django不能给你创建创建数据库,只可以创建表
'USER':'root',
'PASSWORD':'123456',
'HOST':'127.0.0.1', # 你要用的数据库的地址,本机的mysql的话就是127.0.0.1,也可是localhost
'PORT':'3306', # 默认端口是3306
}
}
以上搞完,算是成功了一半了!但也可能会出现一个错误,哈哈哈,下面有解决方法,遇到错误去解决才会学到东西啊!
创建表的结构
在blog下的models.py文件中:
from django.db import models
# Create your models here.
class UserInfo(models.Model):
name = models.CharField(max_length=32) # name 是一个字符串类型
password = models.CharField(max_length=64)
age = models.IntegerField() # age 是一个整型
"""
执行上面的语句相当于下面的sql语句
create table blogsys_UserInfo( # django 读到UserInfo这个类的时候就会创建 App名称_类名 的一个表
id bigint auto_increment primary key, # django会自动为表添加序号
name varchar(32),
password varchar(64),
age int
)
"""
这时你去查看你刚创建的数据库,会发现里面是空的,因为你还没有迁移啊,大宝贝(migrate)
mysql -uroot -p123456
use django_db;
show tables;
table表的迁移
python3 manage.py makemigrations
python3 manage.py migrate # oh no!你可能会发现他报错了!没有报错的话略过下面。
如果他的报错信息是下面这样的:
django.db.utils.OperationalError: (1698, "Access denied for user 'root'@'localhost'")
说明是你访问root用户下的数据库的的权限不够
解决办法:创建一个新的用户,并给予权限
-- 为了照顾小白,写详细一点,其实我也是copy了一些
-- 不区分大小写,用下面的语句去创建abcde用户,并设置密码12345678
/*
CREATE USER 'username'@'host' IDENTIFIED BY 'password';
username:你将创建的用户名
host:指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost,如果想让该用户可以从任意远程主机登陆,可以使用通配符%
password:该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器
对于密码规则,自行百度吧,或者看我另一条文章。。。。。。。。。。。。。。
*/
CREATE USER 'abcde'@'%' IDENTIFIED BY '12345678';
-- 下面的语句 授予用户abcde权限
/*
GRANT privileges ON databasename.tablename TO 'username'@'host'
privileges:用户的操作权限,如SELECT,INSERT,UPDATE等,如果要授予所的权限则使用ALL
databasename:数据库名 tablename:表名,如果要授予该用户对所有数据库和表的相应操作权限则可用表示,如.*
例子:
GRANT SELECT, INSERT ON test.user TO 'pig'@'%';
GRANT ALL ON *.* TO 'pig'@'%';
上面的第一行代码表示在test库中的user 授权pid用户,授权插入和选择操作;第二行表示授权pid用户可以操作所有的权限;
注意: 用以上命令授权的用户不能给其它用户授权,如果想让该用户可以授权,用以下命令:
GRANT privileges ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION;
*/
GRANT ALL ON *.* TO 'abcde'@'%';
-- 用户的密码修改,和删除等等操作,不会的百度吧,同样也可看我的另一篇文章。。。。。。
然后再执行一次python3 manage.py migrate
,应该就成功了!还不行就自己百度去吧!
再次查考表,show tables;
,你会发现有一堆表,只管那个blog_UserInfo
表就好了,查看表中的内容,desc blog_userinfo;
,你就会发现表中有内容了:
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| name | varchar(32) | NO | | NULL | |
| password | varchar(64) | NO | | NULL | |
| age | int | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
至此,说明与mysql链接成功!
应用(表、数据或属性的增、删、改、查)
删除表的某个结构
class UserInfo(models.Model):
name = models.CharField(max_length=32) # name 是一个字符串类型
password = models.CharField(max_length=64)
# age = models.IntegerField() # age 是一个整型
/*
删除表的某个结构,只需要把那个结构注释掉或者删除
然后重新执行
Python3 manage.py makemigrations
python3 manage.py migrate
即可
*/
增加表的结构
class UserInfo(models.Model):
name = models.CharField(max_length=32) # name 是一个字符串类型
password = models.CharField(max_length=64)
age = models.IntegerField() # age 是一个整型
size = models.IntegerField()
/*
比如添加了 size 属性
当再执行
Python3 manage.py makemigrations
会弹出这样的提醒
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:
输入 1 :它会提示让你输入一个默认值
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> [输入默认值]
输入 2 :表示我们需要自己在 size = models.IntegerField() 中去定义它的默认值
例如:size = models.IntegerField(default=2)
当然也可以让你新加的属性可以为 空 ,这样就不会弹出上面的提示
size = models.IntegerField(null=True, blank=True)
*/
表中数据的一些操作:
# 对表 blog_UserInfo 进行操作,其属性有 name password age
# 1. 新建数据
UserInfo.objects.create(name="阿斯顿", password="12324", age=1)
# 类名.objects.create()
# 2. 删除数据
UserInfo.objects.filter(id=3).delete() # 删除id=3的数据信息,filter 筛选条件
UserInfo.objects.all().delete() # 删除表中全部的数据
# 3. 获取数据
data_list = UserInfo.objects.all() # 获取数据 是一个queryset类型的数据,一个数据列表,每一项是一个数据对象
for obj in data_list: # 获取每一行的数据
print(obj.name, obj.password, obj.age)
data_list = UserInfo.objects.filter(id=1) # 获取 id=1 的数据信息 也是一个queryset类型
row_obj= UserInfo.objects.all().first() # 获取queryset类型的第一个对象,row_obj 就是一个对象
print(row_obj.name, row_obj.password, row_obj.age)
# 4. 更新数据
UserInfo.objects.all().update(password="3333") # 所有的password都更新成3333
UserInfo.objects.filter(id=2).update(name="asdh") # 修改 id=2 的name
# 注:
# filter() 筛选条件可以有很多,同sql语句,现在就先这样学!