Ajax(Django开发)
- 知识点的回顾:
- 1.Ajax请求
- 2.订单
- 小结
- 3.图表
- 4.关于文件上传
- 4.1基本操作
- 案例:批量上传数据
- 案例:混合数据(Form)
- 4.2启用media
- 案例:混合数据(form)
- 案例:混合数据(ModelForm)
- models.py
- 定义ModelForm
- 视图
- 小结
知识点的回顾:
-
安装Django
pip install django
-
创建Django项目
>>> django-admin startproject mysite
注意:Pycharm可以创建。如果Pycharm创建,记得settings.py中的DIR templates删除。
-
创建app&注册
>>>python manage.py startapp app01 >>>python manage.py startapp app02 >>>python manage.py startapp app03
INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "app01.apps.App01Config" ]
注意:否则app下的models.py写类时,无法在数据库中创建表。
-
配置静态文件路径&模板的路径(放在app目录下)。
-
配置数据库相关操作(MySQL)
-
第三方模块(django3版本)
pip install mysqlclient
-
自己先去MySQL创建一个数据库。
-
配置数据库连接settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': 'gx_day16', # 数据库名称 'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1 'PORT': 3306, # 端口 'USER': 'root', # 数据库用户名 'PASSWORD': 'xxxx', # 数据库密码 } }
-
在app下的models.py中编写
nfrom django.db import models class Admin(models.Model): """ 管理员 """ username = models.CharField(max_length=32, verbose_name='用户名') password = models.CharField(max_length=64, verbose_name='密码') def __str__(self): return self.username class Department(models.Model): """ 部门表 """ title = models.CharField(max_length=32, verbose_name='标题') def __str__(self): return self.title
-
执行两个命令:
>>>python manage.py makemigrations >>>python manage.py migrate
-
-
在url.py,路由(url和函数的关系)
-
在views.py,视图函数,编写业务逻辑
-
templates目录,编写HTML模板(含有模板语法、继承、
{% static 'xx'%}
) -
ModelForm & Form组件,在我们开发增删改查功能
- 生成HTML标签(生成默认值)
- 请求数据进行校验
- 保存到数据库(ModelForm)
- 获取错误信息
-
Cookie和Session,用户登录信息保存起来
-
中间件,基于中间件实现用户认证,基于:
process_request
-
ORM操作
models.User.objects.filter(id="xxx") models.User.objects.filter(id="xxx").order_by("-id")
-
分页组件
1.Ajax请求
2.订单
表结构
class Order(models.Model):
""" 订单 """
oid = models.CharField(max_length=64, verbose_name='订单号')
title = models.CharField(max_length=32, verbose_name='名称')
price = models.IntegerField(verbose_name='价格')
status_choice = (
(1, '待支付'),
(2, '已支付'),
)
status = models.SmallIntegerField(choices=status_choice, verbose_name='状态', default=1)
admin = models.ForeignKey(verbose_name="管理员", to="Admin", on_delete=models.CASCADE)
想要去数据库中获取数据时:对象/字典
# 对象,当前行的所有数据。
row_object = models.Order.objects.filter(id=uid).first()
row_object.id
row_object.title
# 字典,{"id":1,"title":"xx"}
row_dict = models.Order.objects.filter(id=uid).values("id","title").first()
# queryset = [obj,obj,obj]
queryset = models.Order.objects.all()
# queryset = [{"id":1,"title":"xx"},{"id":2,"title":"xx"},]
queryset = models.Order.objects.all().values("id","title")
# queryset = [(1,"xx"),(2,"xx"),]
queryset = models.Order.objects.all().values_list("id","title")
小结
3.图表
- highchart,国外
- echarts,国内
更多参考文档:https://echarts.apache.org/examples/zh/index.html#chart-type-line
4.关于文件上传
4.1基本操作
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="username">
<input type="file" name="avatar">
<input type="submit" name="提交">
</form>
</div>
{% endblock %}
# 'username': ['lingze']
print(request.POST) # 请求体中数据
# {'avatar': [<InMemoryUploadedFile: 1.png (image/png)>]}
print(request.FILES) # 请求发过来的文件
from django.shortcuts import HttpResponse, render
def upload_list(request):
if request.method == 'GET':
return render(request, 'upload_list.html')
# 'username': ['lingze']
# print(request.POST) # 请求体中数据
# {'avatar': [<InMemoryUploadedFile: 1.png (image/png)>]}
# print(request.FILES) # 请求发过来的文件
file_object = request.FILES.get("avatar")
print(file_object.name)
f = open(file_object.name, mode='wb')
for chunk in file_object.chunks():
f.write(chunk)
f.close()
return HttpResponse("....")
案例:批量上传数据
<form method="post" enctype="multipart/form-data" action="/depart/multi/">
{% csrf_token %}
<div class="form-group">
<input type="file" name="exc">
</div>
<input type="submit" value="上传" class="btn btn-info btn-sm">
</form>
def depart_multi(request):
""" 批量上传(Excel文件)"""
# 1、获取用户上传的文件对象
file_object = request.FILES.get('exc')
print(type(file_object))
# 2、直接打开Excel并读取内容
wb = load_workbook(file_object)
sheet = wb.worksheets[0]
# 3、循环获取每一行数据
for row in sheet.iter_rows(min_row=2):
text = row[0].value
exists = models.Department.objects.filter(title=text).exists()
if not exists:
models.Department.objects.create(title=text)
return redirect('/depart/list/')
案例:混合数据(Form)
提交页面时:用户输入数据+文件(输入不能为空、报错)。
- Form生成HTML标签:type=file
- 表单的验证
- form.cleaned_data 获取 数据 + 文件对象
{% extends 'layout.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ title }}</h3>
</div>
<div class="panel-body">
<form method="post" enctype="multipart/form-data" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<span style="color: red">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">提 交</button>
</form>
</div>
</div>
</div>
{% endblock %}
from django.shortcuts import HttpResponse, render
from django import forms
from app01.utils.bootstrap import BootStrapForm
import os
from app01 import models
def upload_list(request):
if request.method == 'GET':
return render(request, 'upload_list.html')
# 'username': ['lingze']
# print(request.POST) # 请求体中数据
# {'avatar': [<InMemoryUploadedFile: 1.png (image/png)>]}
# print(request.FILES) # 请求发过来的文件
file_object = request.FILES.get("avatar")
print(file_object.name)
f = open(file_object.name, mode='wb')
for chunk in file_object.chunks():
f.write(chunk)
f.close()
return HttpResponse("....")
class UpForm(BootStrapForm):
bootstrap_exclude_fields = ['img']
name = forms.CharField(label="姓名")
age = forms.IntegerField(label="年龄")
img = forms.FileField(label="头像")
def upload_form(request):
title = "Form上传"
if request.method == 'GET':
form = UpForm()
return render(request, 'upload_form.html', {'title': title, 'form': form})
form = UpForm(data=request.POST, files=request.FILES)
if form.is_valid():
# {'name': '吴佩琦2', 'age': 19, 'img': <InMemoryUploadedFile: apple.png (image/png)>}
# print(form.cleaned_data)
# 1、读取图片内容,写入到文件夹中并获取文件的路径。
image_object = form.cleaned_data.get("img")
db_file_path = os.path.join("static", "img", image_object.name)
file_path = os.path.join("app01", "static", "img", image_object.name)
f = open(file_path, 'wb')
for chunk in image_object.chunks():
f.write(chunk)
f.close()
# 2、将图片文件路径写入到数据库
models.Boss.objects.create(
name=form.cleaned_data.get("name"),
age=form.cleaned_data.get("age"),
img=db_file_path,
)
return HttpResponse("...")
return render(request, 'upload_form.html', {'title': title, 'form': form})
注意:就目前而言,所有的静态文件都只能放在static目录。
在django的开发过程中两个特殊的文件夹:
- static,存放静态文件的路径,包括:CSS、JS、项目图片。
- media,用户上传的数据的目录。
4.2启用media
在urls.py中进行配置:
from django.conf import settings
from django.urls import path, re_path
from django.views.static import serve
re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
在settings.py中进行配置:
import os
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = "/media/"
在浏览器上访问这个地址:
案例:混合数据(form)
from django.shortcuts import HttpResponse, render
from django import forms
from app01.utils.bootstrap import BootStrapForm
import os
from app01 import models
from django.conf import settings
def upload_list(request):
if request.method == 'GET':
return render(request, 'upload_list.html')
# 'username': ['lingze']
# print(request.POST) # 请求体中数据
# {'avatar': [<InMemoryUploadedFile: 1.png (image/png)>]}
# print(request.FILES) # 请求发过来的文件
file_object = request.FILES.get("avatar")
print(file_object.name)
f = open(file_object.name, mode='wb')
for chunk in file_object.chunks():
f.write(chunk)
f.close()
return HttpResponse("....")
class UpForm(BootStrapForm):
bootstrap_exclude_fields = ['img']
name = forms.CharField(label="姓名")
age = forms.IntegerField(label="年龄")
img = forms.FileField(label="头像")
def upload_form(request):
title = "Form上传"
if request.method == 'GET':
form = UpForm()
return render(request, 'upload_form.html', {'title': title, 'form': form})
form = UpForm(data=request.POST, files=request.FILES)
if form.is_valid():
# {'name': '吴佩琦2', 'age': 19, 'img': <InMemoryUploadedFile: apple.png (image/png)>}
# print(form.cleaned_data)
# 1、读取图片内容,写入到文件夹中并获取文件的路径。
image_object = form.cleaned_data.get("img")
# media_path = os.path.join(settings.MEDIA_ROOT, image_object.name)
media_path = os.path.join("media", image_object.name)
# db_file_path = os.path.join("static", "img", image_object.name)
# file_path = os.path.join("app01", "static", "img", image_object.name)
f = open(media_path, 'wb')
for chunk in image_object.chunks():
f.write(chunk)
f.close()
# 2、将图片文件路径写入到数据库
models.Boss.objects.create(
name=form.cleaned_data.get("name"),
age=form.cleaned_data.get("age"),
img=media_path,
)
return HttpResponse("...")
return render(request, 'upload_form.html', {'title': title, 'form': form})
案例:混合数据(ModelForm)
models.py
class City(models.Model):
""" 老板 """
name = models.CharField(max_length=32, verbose_name='名称')
count = models.IntegerField(verbose_name='人口')
# 本质上数据库也是ChartField,自动保存数据。
img = models.FileField(max_length=128, verbose_name='Logo', upload_to='city/')
定义ModelForm
from app01.utils.bootstrap import BootStrapForm, BootStrapModelForm
class UpModelForm(BootStrapModelForm):
bootstrap_exclude_fields = ['img']
class Meta:
model = models.City
fields = '__all__'
视图
def upload_modal_form(request):
""" 上传文件和数据(ModalForm)"""
title = "ModelForm上传文件"
if request.method == 'GET':
form = UpModelForm()
return render(request, 'upload_form.html', {'form': form, 'title': title})
form = UpModelForm(data=request.POST, files=request.FILES)
if form.is_valid():
# 对于文件:自动保存
# 字段 + 上传路径写入到数据库
form.save()
return HttpResponse("成功")
return render(request, 'upload_form.html', {'form': form, 'title': title})
小结
-
自己手动去写
file_object = request.FILES.get("exc") ...
-
Form组件(表单验证)
request.POST file_object = request.FILES.get("exc") 具体文件操作还是手动自己做。
-
ModelForm(表单验证+自动保存数据库+自动保存文件)
- Media文件夹 - Models.py定义类文件要 img = models.FileField(verbose_name="Logo", max_length=128, upload_to='city/')