执行逻辑的都可以叫做视图函数(包含函数或者类)
路由访问时不加最后不加斜杠/,本质是浏览器内部重定向为用户跳转到加了斜杠的网页(看响应状态码是3开头)。
name属性用来标识数据
引用外部资源没有效果解决方法
我们发现导入的Bootstrap没有效果,发现也找不到此路径下的文件。
方法一:在urls中添加路径
方法二:配置静态文件
我么知道所有的html文件默认都写在templates文件夹下,其实所有的静态文件(css,js,img,前端第三方类库)默认都放在static文件夹下。
到settings.py文件最后找到STATIC_URL = '/static/'加入以下代码
STATIC_URL = '/static/' # 接口前缀,与静态文件存放目录没有任何关系,但默认这个前缀与静态文件存放目录一致
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static') # static是你的静态文件存放目录,可以配置多个目录,因为不同应用目录里面也可以有静态文件目录,会依次查找列表中所有的静态文件目录,找到的话立刻停止,都没有找到返回404
os.path.join(BASE_DIR,'static-x')
]
# HTML文件导入文件时,最前面的反斜杠不能少
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
form表单触发提交数据的动作两种方式
<input type="submit">
<button></button>
form提交数据的地址如何指定及方式?
action属性控制提交的地址
方式:
<!--1.全路径-->
<form action="http://127.0.0.1:8000/login/">
<!--2.只写路径后缀-->
<form action="/login/">
<!--3.不写 (默认往当前路径提交)-->
form表单默认是get请求
注意:去settings.py里面的MIDDLEWARE将csrf那行代码注释掉
根据客户端请求方式的不同执行不同的逻辑代码
request.method
获得请求方式
def login(request):
# 获取用户端提交的请求方式
print(request.method) # 拿到的请求方式是全大写的字符串
if request.method == 'GET': # 若请求是get
return render(request,'login.html')
elif request.method == 'POST': # 若请求是post
return HttpResponse("收到了")
# 简化版本
def login(request):
if request.method == 'POST':
return HttpResponse('OK')
return render(request,'login.html')
获取客户端请求的数据
request.POST:< QueryDict: {'key1': ['value2'], 'key2': ['value2']} >
可看成一个大字典里面存放着客户端post提交的所有数据
request.POST.get('key')
value虽是列表但获取value时得到是单个元素,默认只会取value列表里面的最后一个元素
request.POST.getlist('key')
获取value列表中所有的数据,用户的爱好,多选框等
不推荐request.POST.['key']
获取数据,若key不存在会报错
同理,若请求为get,则将POST改成GET
Django与数据库
用pymsql连接数据库
import pymysql
def login(request):
if request.method == 'POST':
username = request.POST.get('username') # 此username是依据前端form表单中的name属性值
password = request.POST.get('password')
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password ='weiruo95',
database = 'day54',
charset ='utf8',
autocommit = True,
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select * from userinfo where name=%s and password = %s',(username,password)) # 放一个元祖,会自动拼接
user_info = cursor.fetchall()
if user_info:
return HttpResponse('登录成功!')
return render(request,'login.html')
用pycharm连接数据库
点击加号下拉菜单
下载驱动完成后填写相关信息
出现java.lang.RuntimeException错误,是因为JDBC驱动程序的5.2版本与UTC时区配合使用,必须在连接字符串中明确指定serverTimezone
解决方法:
去数据库设置时区 set global time_zone = ‘+8:00’;
找不到数据库解决方法:点击 0 of 7处
操作数据库
Django连接MySQL
settings.py文件下的DATABASES处修改配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 连接数据库种类
'NAME': 'test', # 连接数据库名
'HOST':'127.0.0.1', # IP
'PORT':3306, # 端口
'USER':'root', # 用户名
'PASSWORD':'123456' # 密码
}
}
# 键必须都是大写
告诉Django用pymysql替换它默认mysqldb模块连接数据库
方式1:在你的项目文件夹下面的__init__.py
方式2:也可以在你的应用文件夹下面的__init__.py
# 固定写法
import pymysql
pymysql.install_as_MySQLdb() # 告诉django用pymysql代替mysqldb连接数据库
重新连接其他数据库
右键原数据库,remove,连接流程如上介绍
利用ORM生成类对应一张表
1.应用文件夹下的models.py文件中定义类
class User(models.Model):
# user表的主键字段名设为id且自增
id = models.AutoField(primary_key=True)
# varchar(32)name字段是varchar(32) CharField在定义的时候必须加上max_length参数
name = models.CharField(max_length=32)
password = models.CharField(max_length=16)
2.数据库迁移(同步)命令
python3 manage.py makemigrations
将你的数据库变动记录到文件中,并不会帮你创建一张表
python3 manage.py migrate
将你的数据库变动正在同步到数据库中
新增数据
# 简易网页注册保存信息至数据库
def reg(request):
if request.method=='POST':
# 获取用户名和密码
username = request.POST.get('username')
password = request.POST.get('password')
# 插入数据库
# 方法一:
user_obj = models.User.objects.create(name=username,password=password) # 返回一个User类实例化的对象即数据库内的一行
# 方式二:
user_obj = models.User(name=username,password=password)
user_obj.save()
print(user_obj)
print(user_obj.pk) # pk对应主键名,此处换为id是一样的
print(user_obj.name)
print(user_obj.password)
return HttpResponse('注册成功!')
return render(request,'reg.html')
<div class="container">
<div class="row">
<h1>注册页面</h1>
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
<p>username:<input type="text" name="username" class="form-control"></p>
<p>password:<input type="password" name="password" class="form-control"></p>
<input type="submit" class="btn btn-primary">
</form>
</div>
</div>
</div>
查看数据
def userlist(request):
# 获取数据库数据
user_list = models.User.objects.all()
# print(user_list) # <QuerySet [<User: User object>, <User: User object>, <User: User object>, <User: User object>]> 更改__str__方法后<QuerySet [<User: moon>, <User: hysen>, <User: pinking>, <User: muzier>]>
# # print(user_list.query) # 只要是QuerySet对象,都能.query获得当前QuerySet对象内部的sql语句 SELECT `app01_user`.`id`, `app01_user`.`name`, `app01_user`.`password` FROM `app01_user`
# # for user_obj in user_list:
# # print(user_obj.id,user_obj.name,user_obj.password)
return render(request,'userlist.html',locals())
# 重定向 可以写别人的网址也可以是自己的路径
<div class="container">
<div class="row">
<h1>数据展示</h1>
<div class="col-md-8 col-md-offset-2">
<table class="table table-striped table-hover table-bordered">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>password</th>
</tr>
</thead>
<tbody>
{% for user_obj in user_list %}
<tr>
<td>{{ user_obj.pk }}</td>
<td>{{ user_obj.name }}</td>
<td>{{ user_obj.password }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
user_list是一个QuerySet数据类型,列表套着多个对象:<QuerySet [<User: User object>, <User: User object>, <User: User object>, <User: User object>]>
只要是QuerySet对象,都能.query获得当前QuerySet对象内部的sql语句
视图函数必须返回一个HTTPResponse对象 不然会报错ValueError: The view app01.views.userlist didn't return an HttpResponse object. It returned None instead
其实render和redirect返回的也是HTTPResponse对象
模板语法中{{ }}与变量有关,{{%%}}与逻辑相关
查询数据需要注意的是你获取到的到底是一个queryset还是一个数据对象,如果你是要获取数据对象,first千万别忘了
user_query = models.User.objects.filter(id=edit_id).first()
filter和get获取数据的区别
filter当条件不存在的情况下会返回一个空的queryset对象
<QuerySet []> <class 'django.db.models.query.QuerySet'>
用get可以直接获取到数据对象本身但是查询条件不存在的情况下直接报错
user_obj = models.User.objects.get(id=edit_id)
新增数据按钮
<!--利用a标签href属性 可以指定页面跳转的路径 href可以写全路径 但是推荐写后缀即可-->
<a href="/reg/" class="btn btn-default" >新增数据</a>
<!--必须记得href后加的路径,前面斜杠/必须加,不然只是在当前路径后面拼接你加的路径。-->
models里类的变动
修改模型层里面的跟表相关的所有的数据,只要你修改了就必须重新执行数据库迁移命令,同时如果你的数据库中有记录,那么需要为原有记录的新增字段添加默认值。
编辑数据
# 编辑对象的id的获取方式
# 方式1:利用input隐藏一个标签
<input type="hidden" name="edit_id" value="{{ user_obj.pk }}">
# 方式2:
<form action="/edit/?edit_id={{ user_obj.pk }}" method="post">
# 注意:queryset对象点修改 删除 会作用于对象内部所有的数据对象 类似于批量操作
# 方式1:
models.User.objects.filter(id=edit_id).update(name=username,password=password)
# 方式2:获取到当前数据对象
user_obj = models.User.objects.filter(id=edit_id).first()
user_obj.name = username
user_obj.save()
删除数据
models.User.objects.filter(id=1).delete() # 会将queryset所有的数据对象全部删除