根据标题类型进行筛选
url设计:
url(r'^all/(?P<type_of_news_id>\d+)/', views.index),
url(r'^', views.index),
前端页面设计:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
ul {
margin-left: 20%;
margin-right: 20%;
}
ul li {
display: inline-block;
font-weight: 700;
font-family: 楷体;
font-size: 30px;
margin-left: 20px;
background-color: wheat;
border: solid 1px;
}
</style>
</head>
<body>
<ul>
{% if current_type_of_news_id %}
<li><a href="/">全部</a></li>
{% else %}
<li><a style="color: blue;background-color: red" href="/">全部</a></li>
{% endif %}
{% for item in news_types %}
{% if item.id == current_type_of_news_id %}
<li><a style="color: blue;background-color: red" href="/all/{{ item.id }}/">{{ item.news_type }}</a></li>
{% else %}
<li><a href="/all/{{ item.id }}/">{{ item.news_type }}</a></li>
{% endif %}
{% endfor %}
</ul>
<h2>新闻列表</h2>
<div>
{% for news in news_list %}
<div>{{ news.title }}</div>
{% endfor %}
</div>
</body>
</html>
后台设计:
def index(request,*args,**kwargs):
"""
function:返回首页
-显示所有的新闻类型、显示所有的新闻列表
"""
print(kwargs)
current_type_of_news_id = kwargs.get('type_of_news_id')
print(type(current_type_of_news_id)) #str
"""
之所有用kwargs.get('type_of_news_id'),而不是kwargs['type_of_news_id']因为
后者会报错.
{}
None
url穿参,我们拿到的都是str类型,但是我们从数据库当中获得的是数值类型的
"""
if current_type_of_news_id:
current_type_of_news_id = int(current_type_of_news_id)
news_types = models.NewsType.objects.all()
news_list = models.NewsTable.objects.filter(**kwargs).all()
"""
filter(**{'type_of_news_id':3}) 等价于 filter(type_of_news_id=3)
filter(**{})无条件就是所有
"""
return render(request,'index.html',{'news_types':news_types,
'news_list':news_list,
'current_type_of_news_id':current_type_of_news_id})
效果展示:
基于数据库事务性特点实现点赞的功能
后台点赞逻辑,前端刷新版(前端页面没有随着静态加1)
前端代码:
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
ul {
margin-left: 20%;
margin-right: 20%;
}
ul li {
display: inline-block;
font-weight: 700;
font-family: 楷体;
font-size: 30px;
margin-left: 20px;
background-color: wheat;
border: solid 1px;
}
</style>
</head>
<body>
<h1>新闻类型</h1>
<ul>
{% if current_type_of_news_id %}
<li><a href="/">全部</a></li>
{% else %}
<li><a style="color: blue;background-color: red" href="/">全部</a></li>
{% endif %}
{% for item in news_types %}
{% if item.id == current_type_of_news_id %}
<li><a style="color: blue;background-color: red" href="/all/{{ item.id }}/">{{ item.news_type }}</a></li>
{% else %}
<li><a href="/all/{{ item.id }}/">{{ item.news_type }}</a></li>
{% endif %}
{% endfor %}
</ul>
<h1>新闻列表</h1>
<div>
{% for news in news_list %}
<div>
<div>{{ news.title }}</div>
<div> 发布者:{{ news.publisher.username }} - 评论个数:{{ news.comment_count }} - <a class="news-like" href="#" news_id="{{ news.id }}">赞:{{ news.favor_count }}</a></div>
<br>
</div>
{% endfor %}
</div>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script>
{#接下来我们给赞标签添加相应的事件,框架加载完成之后执行function#}
$(function(){
bindFavorEvent();
})
function bindFavorEvent() {
$('.news-like').click(function(){
{#获取当前新闻的ID并向后台发送相应的数据#}
var newId = $(this).attr('news_id');
$.ajax({
url:'/do_like.html',
type:'POST',
data:{'newId':newId},
dataType: 'JSON',
success:function (arg) {
{# 发送成功之后等待相应的参数#}
if (arg.status){
{# 如果点赞成功 #}
alert(arg.msg)
alert('点赞成功')
}else{
{# 如果点赞失败 #}
alert(arg.msg)
alert('点赞失败')
}
}
})
})
}
</script>
</body>
</html>
后台逻辑:
def do_like(request,*args,**kwargs):
"""
function:用户点赞
print(request.POST)
print(request.POST.urlencode())
print(request.POST.get('newId'))
<QueryDict: {'newId': ['1'], 'name': ['angela']}>
newId=1&name=angela
1
"""
# 创建一个response对象
response = BaseResponse()
print(response.status,response.data,response.msg)
# 通过session获取用户登录的ID
# user_id = request.session.get(user_id)
user_id = 1
newId = request.POST.get('newId')
try:
with transaction.atomic():
# Django中插入数据使用create,首先现在赞表中加入一条记录,并在新闻表当中更新favor_count的数值
models.FavorTable.objects.create(user_id=user_id,news_id = newId)
models.NewsTable.objects.filter(id=newId).update(favor_count=F('favor_count')+1)
except Exception as e:
print('抛出异常...')
response.msg = str(e)
else:
print('没有抛出异常,处理成功...')
response.status = True
"""
response = {'status':True,'data':None,'msg':None}
return HttpResponse(json.dumps(response))
response = BaseResponse()
json不能够直接序列化上面的这个对象
"""
# 最后只返回一个response对象
print('--------------')
print(response.__dict__)
"""
{'data': None, 'msg': None, 'status': True}
{'data': None, 'msg': 'UNIQUE constraint failed: app01_favortable.user_id, app01_favortable.news_id', 'status': False}
"""
return HttpResponse(json.dumps(response.get_dict()))
效果展示:(只有刷新当前页面才会看到点赞加一的效果)
重要的地方:
后台点赞,前端页面不自动刷新。(不抛出异常版本)
核心代码:
with transaction.atomic():
if exist_favor:
# 如果点赞已经存在
models.FavorTable.objects.filter(user_id=user_id,news_id = newId).delete()
models.NewsTable.objects.filter(id=newId).update(favor_count=F('favor_count') - 1)
else:
# 如果点赞不存在
models.FavorTable.objects.create(user_id=user_id,news_id = newId)
models.NewsTable.objects.filter(id=newId).update(favor_count=F('favor_count')+1)
后台点赞:前端页面自动刷新版本(无动画效果)
代码示例:
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
ul {
margin-left: 20%;
margin-right: 20%;
}
ul li {
display: inline-block;
font-weight: 700;
font-family: 楷体;
font-size: 30px;
margin-left: 20px;
background-color: wheat;
border: solid 1px;
}
</style>
</head>
<body>
<h1>新闻类型</h1>
<ul>
{% if current_type_of_news_id %}
<li><a href="/">全部</a></li>
{% else %}
<li><a style="color: blue;background-color: red" href="/">全部</a></li>
{% endif %}
{% for item in news_types %}
{% if item.id == current_type_of_news_id %}
<li><a style="color: blue;background-color: red" href="/all/{{ item.id }}/">{{ item.news_type }}</a></li>
{% else %}
<li><a href="/all/{{ item.id }}/">{{ item.news_type }}</a></li>
{% endif %}
{% endfor %}
</ul>
<h1>新闻列表</h1>
<div>
{% for news in news_list %}
<div>
<div>{{ news.title }}</div>
<div> 发布者:{{ news.publisher.username }} - 评论个数:{{ news.comment_count }} - 赞:<a class="news-like" href="#" news_id="{{ news.id }}">{{ news.favor_count }}</a></div>
<br>
</div>
{% endfor %}
</div>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script>
{#接下来我们给赞标签添加相应的事件,框架加载完成之后执行function#}
$(function(){
bindFavorEvent();
})
function bindFavorEvent() {
$('.news-like').click(function(){
{#获取当前新闻的ID并向后台发送相应的数据#}
var obj = $(this);
var newId = $(this).attr('news_id');
$.ajax({
url:'/do_like.html',
type:'POST',
data:{'newId':newId},
dataType: 'JSON',
success:function (arg) {
{# 发送成功之后等待相应的参数#}
if (arg.status){
{# 如果点赞成功+1 #}
orign = obj.text();
new_value = parseInt(orign) + 1;
obj.text(new_value);
}else{
{# 如果点赞失败-1#}
orign = obj.text();
new_value = parseInt(orign) - 1;
obj.text(new_value);
}
}
})
})
}
</script>
</body>
</html>
效果展示:
点赞:前端页面自动刷新版本(含有动画效果,推荐)
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
ul {
margin-left: 20%;
margin-right: 20%;
}
ul li {
display: inline-block;
font-weight: 700;
font-family: 楷体;
font-size: 30px;
margin-left: 20px;
background-color: wheat;
border: solid 1px;
}
</style>
</head>
<body>
<h1>新闻类型</h1>
<ul>
{% if current_type_of_news_id %}
<li><a href="/">全部</a></li>
{% else %}
<li><a style="color: blue;background-color: red" href="/">全部</a></li>
{% endif %}
{% for item in news_types %}
{% if item.id == current_type_of_news_id %}
<li><a style="color: blue;background-color: red" href="/all/{{ item.id }}/">{{ item.news_type }}</a></li>
{% else %}
<li><a href="/all/{{ item.id }}/">{{ item.news_type }}</a></li>
{% endif %}
{% endfor %}
</ul>
<h1>新闻列表</h1>
<div>
{% for news in news_list %}
<div>
<div>{{ news.title }}</div>
<div> 发布者:{{ news.publisher.username }} -
评论个数:{{ news.comment_count }} -
{# 通过 inline-block 防止另起一行 #}
<div style="display: inline-block;position: relative">
赞:<a class="news-like" href="#" news_id="{{ news.id }}">{{ news.favor_count }}</a>
</div>
</div>
<br>
</div>
{% endfor %}
</div>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script>
{#接下来我们给赞标签添加相应的事件,框架加载完成之后执行function#}
$(function () {
bindFavorEvent();
})
function bindFavorEvent() {
$('.news-like').click(function () {
{#获取当前新闻的ID并向后台发送相应的数据#}
{#在Ajax操作的时候,回调函数中的$(this)已经不是原来的$(this)#}
var obj = $(this);
var newId = $(this).attr('news_id');
$.ajax({
url: '/do_like.html',
type: 'POST',
data: {'newId': newId},
dataType: 'JSON',
success: function (arg) {
{# 发送成功之后等待相应的参数#}
if (arg.status) {
{# 如果点赞成功+1 #}
var orign = obj.text();
var new_value = parseInt(orign) + 1;
obj.text(new_value);
showLikeCount(obj,"+1");
} else {
{# 如果点赞失败-1#}
var orign = obj.text();
var new_value = parseInt(orign) - 1;
obj.text(new_value);
showLikeCount(obj,"-1");
}
}
})
})
}
{# 设置几个全局变量 #}
function showLikeCount(obj,num) {
{#用于动画点赞的效果#}
var fontSize = 20;
var left = 25;
var bottom = 10;
var opacity = 1;
var tag = document.createElement('span');
tag.innerText = num;
tag.style.position = 'absolute';
tag.style.fontSize = fontSize + "px";
tag.style.left = left + "px";
tag.style.bottom = bottom + "px";
tag.style.opacity = opacity;
tag.style.color = "red";
{# 下面一行的含义是在a标签的后面加1 #}
obj.after(tag)
timer = setInterval(function () {
fontSize += 15;
left += 5;
bottom += 5;
opacity -= 0.5;
tag.style.fontSize = fontSize + "px";
tag.style.left = left + "px";
tag.style.bottom = bottom + "px";
tag.style.opacity = opacity;
tag.style.color = "red";
if (opacity <= 0) {
{# 清楚定时器,timer利用闭包找到的 #}
clearInterval(timer);
{# 通过remove标签直接自己删除 #}
tag.remove();
}
}, 200)
}
</script>
</body>
</html>
效果展示:
上传文件
enctype=”multipart/form-data”什么意思?
参考答案:https://zhidao.baidu.com/question/808172048640950732.html
方式1:Form表单的方式上传(页面刷新、不能预览)
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/upload/" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="fffff">
<input type="submit" value="提交">
</form>
</body>
</html>
代码示例:
def upload(request,*args,**kwargs):
if request.method == "GET":
return render(request,'upload.html')
else:
file_obj = request.FILES.get('fffff')
print('文件的名字是:%s' % file_obj.name)
fw = open(file_obj.name,'wb')
for chunk in file_obj.chunks():
fw.write(chunk)
fw.close()
return render(request,'upload.html')
方式2:Ajax上传文件:依赖于FormData,对于兼容性不好
模板:
Ajax上传文件:依赖于FormData,对于兼容性不好
优点:不刷新页面
<h1>Ajax上传文件:依赖于FormData,对于兼容性不好</h1>
<input type="file" id="ggggg">
<a id="btn1">提交</a>
Ajax方式发送:
function bindLoadImage() {
$('#btn1').click(function () {
var form = new FormData();
var fileObj = document.getElementById('ggggg').files[0]
form.append('fffff',fileObj)
form.append('k1','v1')
form.append('k2','v2')
$.ajax({
url:"/ajax-upload/",
type:'POST',
data:form,
{# 发送文件的时候必须写下面两行 #}
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
success:function (arg) {
console.log(arg);
}
})
})
}
具体代码:
前端页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Ajax上传文件:依赖于FormData,对于兼容性不好</h1>
{# 缺点:FormData这种方式不适合高级浏览器 优点:不刷新页面#}
{# 通过Ajax的方式上传,只需要写上一个input框就可以了 #}
<input type="file" id="ggggg">
<a id="btn1">提交</a>
</body>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script>
{# 页面加载完成之后自动执行 #}
$(function () {
bindLoadImage();
})
function bindLoadImage() {
$('#btn1').click(function () {
var form = new FormData();
{# 里面写的是key和文件对象 #}
{# 标签对象:document.getElementById('ggggg') #}
{# 文件对象:document.getElementById('ggggg').files[0] #}
{# 文件对象:$('#ggggg')[0].files[0] #}
var fileObj = document.getElementById('ggggg').files[0]
form.append('fffff',fileObj)
{# Form表单中的其他数据可以用下面这种方式进行包装 #}
form.append('k1','v1')
form.append('k2','v2')
console.log(document.getElementById('ggggg'));
console.log($('#ggggg'));
console.log($('#ggggg')[0]);
console.log($('#ggggg')[1]);
$.ajax({
url:"/ajax-upload/",
type:'POST',
{# 下面这里怎么写,大家一定要注意:向后台发送文件和字符串肯定不是一样的 #}
data:form,
{# 发送文件的时候必须写下面两行 #}
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
success:function (arg) {
console.log(arg);
}
})
})
}
</script>
</html>
后台:
def ajax_upload(request,*args,**kwargs):
file_obj = request.FILES.get('fffff')
print(request.POST.get('k1')) # v1
print('你好你好')
print('文件的名字是:%s' % file_obj.name)
fw = open(file_obj.name, 'wb')
for chunk in file_obj.chunks():
fw.write(chunk)
fw.close()
return HttpResponse(json.dumps('OK'))
关于Jquery的地方:
参考网址:http://www.cnblogs.com/wupeiqi/articles/5354900.html
方式3:Form+Ifrme 伪造发送Ajax,伪Ajax,兼容性更好
凉菜:实现在线搜的效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>第三种发送数据的方式</title>
</head>
<body>
<form>
<input type="text">
<input type="submit" value="提交">
</form>
<input type="text">
<input type="text" placeholder="请输入关键字" id="key"><input type="button" onclick="searchSB();" value="搜索">
<div class="container">
<iframe style="width: 600px;height: 1000px" src="https://www.baidu.com/s?wd=xingpu" id="im1"></iframe>
<iframe style="width: 600px;height: 1000px" src="https://www.sogou.com/web?query=xingpu" id="im2"></iframe>
</div>
</body>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script>
function searchSB() {
var val = $('#key').val()
$('#im1').attr("src","https://www.baidu.com/s?wd="+val);
$('#im2').attr("src","https://www.sogou.com/web?query="+val);
}
</script>
</html>
static下面的静态文件是可以直接看到的:
如何上传文件:
总结:
上传文件的三种方式:
1、基于原始Form表单的方式
缺点:页面会刷新、不能预览
2、Ajax上传文件(基于FormData)
优点:页面不刷新
缺点:兼容性不好
预览:?
3、Form+Ifrme 伪造发送Ajax,伪Ajax,兼容性更好
<iframe style="width: 100%;height: 2000px" src="http://www.autohome.com.cn"></iframe>
- iframe,天生局部刷新,但是只能通过get方式向后台发送数据
- form,天生整个页面刷新 ,但是可以通过post方式向后台发送数据
总结:iframe + form = 局部刷新 + post方式传送数据
*****(重点)form表单中的target属性 和 iframe中的name属性值相同的时候,
form就不会通过页面刷新的方式提交,而是静态局部的提交。
结果:将数据发送过去了,并且将返回值返回到iframe标签里面去了。
==> 所以以后我们将iframe标签里面的数值拿到,就是后台返回的结果.
==> 页面不刷新,向后台发送数据了。
==>问题1:如果获取iframe中的内容呢?(注意事项:)
错误答案:直接取标签里面的内容。。。
<iframe src="" name="xxxxx" style=""></iframe>
<iframe src="" name="xxxxx" style="">
#document
<html>
<head></head>
<body>{"msg": null, "data": "static\\images\\iframe.png", "status": true}</body>
</html>
</iframe>
jquery: var t1 = $("#ifm").contents().find("body").text();
注意:Jquery可能由于版本的原因不能出现相应的数值。
DOM的方式: var t2 = document.getElementById("ifm").contentWindow.document.body.innerHTML;
结果:"{"msg": null, "data": "static\\images\\qinshi.jpg", "status": true}"
我们在变成字典这种样式.
JSON.parse(content)
{msg: null, data: "static\images\qinshi.jpg", status: true}
==>问题2:如何确定数据已经上传成功了呢?
毕竟我们应该在文件上传成功之后,我们才应该点击提交。
onload():当标签内容加载完成之后,就会执行。
<iframe id="ifm" src="" name="xxxxx" style="" onload="successCallback();" ></iframe>
第一次会报错:
Uncaught ReferenceError: successCallback is not defined
at HTMLIFrameElement.onload ((index):16)
原因:第一次从上到下进行加载,所以会报错;
但是后来如果内容上传了,则不会加载。
所以第一次报错,对我们并没有什么影响。
部分输出结果展示:
function successCallback(thisobj) {
{# thisobj指的就是最外面的iframe标签 #}
var data = thisobj.contentWindow.document.body.innerHTML;
console.log(data)
data = JSON.parse(data)
console.log(data)
}
运行结果:格式的转换
{"msg": null, "data": "static\\images\\\u5982\u4f55\u52a0\u53c2\u6570.png", "status": true}
(index):25 {msg: null, data: "static\images\如何加参数.png", status: true}
==> 问题3:如何让返回的图片在页面中进行显示呢?
function successCallback(thisobj) {
{# thisobj指的就是最外面的iframe标签 #}
var response = thisobj.contentWindow.document.body.innerHTML;
console.log(response)
response = JSON.parse(response)
console.log(response)
var img = document.createElement('img')
{# data在这里面指的是路径 #}
img.src = "/"+response.data;
console.log(img.src)
$("#imgList").append(img)
}
从上面我们可以看出,在创建img标签的同时,指定src即可。
总结:普通的POST请求:
-- 普通的Ajax
-- 或者伪造的Ajax
但是上传文件:
最好用伪造Ajax。
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" placeholder="默认值看看刷新之后在不在">
{# form表单中的target属性 和 iframe中的name属性值相同 #}
<form method="POST" target="xxxxx" action="/upload3/" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="user">
<input type="file" name="avator">
<input type="submit" value="提交">
</form>
<iframe id="ifm" src="" name="xxxxx" style="display: none" onload="successCallback(this);" ></iframe>
<div>预览的地方</div>
<div id="imgList"></div>
</body>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script>
function successCallback(thisobj) {
{# thisobj指的就是最外面的iframe标签 #}
var response = thisobj.contentWindow.document.body.innerHTML;
console.log(response)
response = JSON.parse(response)
console.log(response)
var img = document.createElement('img')
{# data在这里面指的是路径,静态文件前面还要加上一个/ #}
img.src = "/"+response.data;
img.style.width = 1000 + "px";
img.style.height = 600 + 'px';
console.log(img.src)
$("#imgList").append(img)
}
</script>
</html>
后台逻辑:
def upload3(request,*args,**kwargs):
if request.method == "GET":
return render(request, "upload3.html")
else:
try:
response = BaseResponse()
user = request.POST.get('user')
obj = request.FILES.get('avator')
print(user,obj.name)
# 拼接路径的方式
img_path = os.path.join('static','images',obj.name)
"""
fds bb.png
static\images\juesha.png
"""
with open(img_path,mode='wb') as fw:
for chunk in obj.chunks():
fw.write(chunk)
except Exception as e:
response.msg = str(e)
else:
response.status = True
response.data = img_path
#在前端界面通过解析img_path我们就可以读取图像了
return HttpResponse(json.dumps(response.__dict__))
效果展示:
优化1:不用点击submit按钮,直接上传。
利用onchange():内容改变的时候自动的触发。a标签可以提交表单(你懂得).
前端代码:参考的是a+form
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" placeholder="默认值看看刷新之后在不在">
{# form表单中的target属性 和 iframe中的name属性值相同 #}
<form id="ff1" method="POST" target="xxxxx" action="/upload3/" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="user">
<input onchange="changeImg();" type="file" name="avator">
</form>
<iframe id="ifm" src="" name="xxxxx" style="display: none" onload="successCallback(this);" ></iframe>
<div>预览的地方</div>
<div id="imgList"></div>
</body>
<script src="/static/js/jquery-1.11.3.min.js"></script>
<script>
function successCallback(thisobj) {
{# thisobj指的就是最外面的iframe标签 #}
var response = thisobj.contentWindow.document.body.innerHTML;
console.log(response)
response = JSON.parse(response)
console.log(response)
var img = document.createElement('img')
{# data在这里面指的是路径,静态文件前面还要加上一个/ #}
img.src = "/"+response.data;
img.style.width = 1000 + "px";
img.style.height = 600 + 'px';
console.log(img.src)
$("#imgList").append(img)
}
function changeImg() {
{# 只要内容一修改,就会触发这个函数 #}
document.getElementById("ff1").submit();
}
</script>
</html>
优化2:改进的地方2:选择文件按钮进行改进
代码对比:
2、改进的地方2:选择文件按钮进行改进
原来的是这样的:
<form method="POST" target="xxxxx" action="/upload3/" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="user">
{# 下面这个是上传文件的标签 #}
<input type="file" name="avator">
<input type="submit" value="提交">
</form>
改进后:
<form method="POST" target="xxxxx" action="/upload3/" enctype="multipart/form-data">
{% csrf_token %}
<input type="text" name="user">
{# 下面这个是上传文件的标签 #}
<a style="display:inline-block;text-align:center;line-height:50px;width: 70px;border-radius: 5px;height: 50px;background-color: darkslateblue;color: white;position: relative">
上传文件
<input type="file" name="avator" style="position: absolute;left: 0;top: 0;right: 0;bottom: 0;opacity: 0">
</a>
<input type="submit" value="提交">
</form>
效果展示: