静态文件配置
在settings.py中最底下有一个叫做static的文件夹,主要用来加载一些模板中用到的资源,提供给全局使用
这个静态文件主要用来配置CSS,HTML,图片,字体文件等
STATIC_URL
= '/static/'
STATICFILES_DIRS
= [
os.path.join(BASE_DIR,'static')
]
之后在模板中,首先加载静态文件,之后调用静态,就不用写绝对全路径了
模板中的声明{% load static%}
`或 {% load
staticfiles %}`<br />在引用资源的时候使用<br />`{% static 'xxx' %} xxx
就是相对于staticfiles_dirs
的`一个位置
静态文件和模板文件的区别
先建静态文件夹
记得settings添加配置:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
新建url:
url('^index/', views.index, name='index'),
在Templates中新建html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h2>这是一个首页</h2>
<h4>{{ username }}</h4>
</body>
</html>
views:
def index(request):
# 模板html支持模板语言,可以挖坑填坑
return render(request, 'index.html')
我们可以访问模板html文件
我们先前在html中进行了挖坑,只是没有填坑,而在访问时服务器自动优化了挖坑的代码
接着在static文件夹中新建html文件夹,在其中新建index.html文件
static文件夹用于存放静态资源,我们可以直接通过网址访问其中的静态资源
我们可以上传图片,静态页面。
**
可以观察到静态html中不支持模板语言是静态的
而在模板中的HTML是动态的,会帮我们处理渲染
以后将静态资源放入static中,效率会比放在模板中的效率高,因为MTV中对模板会渲染处理。
文件上传
原理类似于文件复制,一边读取文件,一边写入文件,而文件上传是从网络上读取文件。
文件数据存储在request.FILES属性中
form表单上传文件需要添加enctype='multipart/form-data'
请求方式
存储
在static文件夹下创建uploadefiles用与存储接收上传的文件
在settings中配置,MEDIA_ROOT=os.path.join(BASE_DIR,r'static/uploadefiles')
在开发中通常是存储的时候,我们要存储到关联用户的表中
实践:文件上传
url:
url('^uploadfile', views.upload_files, name='upload_files'),
模板:upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="{% url 'app:upload_files' %} " method='post' enctype="multipart/form-data">
{# 因为上传文件,一个文件可能很大,所以在传输过程中会将文件分块,打包,然后加密传输 #}
{% csrf_token %} {# post提交需要csrf_token #}
<span>文件</span><input type="file" name="icon">
<br>
<input type="submit" name="上传">
</form>
</body>
</html>
views:
def upload_files(request):
# 判断请求方式
if request.method == 'GET': # 如果是get,就返回一个渲染页面
return render(request, 'upload.html')
elif request.method == 'POST': # 用来接收客户端上传的数据
icon = request.FILES.get('icon')
# 打印上传的文件
print(icon)
return HttpResponse('上传成功')
我们先打印出来刚刚客户端上传的文件,后续再实现保存文件的功能。
然后进行测试:
可以看到成功打印上传文件
接着我们实现保存功能
views改为:
def upload_files(request):
# 判断请求方式
if request.method == 'GET': # 如果是get,就返回一个渲染页面
return render(request, 'upload.html')
elif request.method == 'POST': # 用来接收客户端上传的数据
icon = request.FILES.get('icon')
print(type(icon))
# 新建一个文件,然后将上传的文件写入数据,写入形式是二进制文件
with open(r'static/img/icon.jpg', 'wb') as save_file:
for part in icon.chunks(): # 将传过来的文件一行一行的读取
save_file.write(part) # 将传过来的文件一行一行的写入
save_file.flush()
return HttpResponse('上传成功')
下面来尝试:
选择一张照片然后点击提交
我们也可以在文件夹中找到图片
这样我们就成功上传了图片,这种方法是“万金油”,是原生写法,因为不光在DJango中可以,在flask中也这一这样写,但是这样写不够简洁。
实践:文件上传Pro
我们可以在models添加模型:
class UerModel(models.Model):
u_name = models.CharField(max_length=16)
# upload_to代表将文件传到哪个地方,我们的路径写的是相对路径,相对于MTDIA_ROOT 媒体根目录
u_icon = models.ImageField(upload_to='icons')
接着我们在static文件夹中创建upload文件夹(也可以在其他地方进行创建,只需要能够访问到即可)
另外我们还要在settings.py中注册路径:
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/upload')
我们在model中用到了ImageField来保存图像,但是辨别文件是否为图像,处理图像,我们需要专门处理图像的库Pillow。
安装Pillow(目前观察到这个库已经内置了,在安装的时候提示已安装)
新建url:这个url做为我们上传图片
url('^imagefield/', views.image_field, name='image_field'),
views:
def image_field(request):
if request.method == 'GET':
return render(request, 'image_field.html')
elif request.method == 'POST':
# 获取用户名
username = request.POST.get('username')
# 获取图片
icon = request.FILES.get('icon')
print(icon)
print(username)
user = UserModel()
user.u_name = username
user.u_icon = icon
user.save()
return HttpResponse('上传成功%d' % user.id)
注意获取username是用POST.get,
而获取图片文件使用FILES.get来获取,假如获取形式不对应会造成获取值为None
也可以看到成功打印出了上传文件名以及用户名。
而且这种方法,上传文件名相同时,会在重复图片后面自动追加一串混淆字符串。
接着我们新建url用来获取用户头像:
url('^mine/', views.mine, name='mine'),
views:
def mine(request):
# 获取username
username = request.GET.get('username')
user = UserModel.objects.get(u_name=username)
# 获取图片保存的路径
print('/static/upload/'+user.u_icon.url)
data = {
'username': username,
'icon_url': '/static/upload/'+user.u_icon.url
}
return render(request, 'mine.html', context=data)
新建mine.html用来当作个人中心的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mine</title>
</head>
<body>
<h3>{{ username }}</h3>
<img src="{{ icon_url }}" alt="{{ username }}">
</body>
</html>
可以看到访问username=2时:
linux有个bug当一个文件夹里面的直接子文件数大于65535时,文件夹再也打不开。
有时候只有接触到大量数据,真实的生产环境时,才能遇到更深的问题。
为了将上传的文件规划存放起来,并且控制每一个文件夹中的文件数量。
我们可以在upload_to=''中调整:
(记得修改完迁移文件)
class UserModel(models.Model):
u_name = models.CharField(max_length=16)
# upload_to后面填路径,表示上传的图片存放文件夹,我们的路径写的是相对路径,相对于MTDIA_ROOT 媒体根目录
u_icon = models.ImageField(upload_to='%Y/icons')
%Y/ 代表了按年划分文件夹
我们还可以进一步使用%Y%m%d/icons
一直细化到天来自动创建文件夹用于存放
此处评论已关闭