首先上一個htmlcss
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/blog/bs/css/bootstrap.css"> <script src="/static/js/jquery-3.2.1.min.js"></script> <style> #avatar_img { margin-left: 20px; } #avatar { display: none; } .error { color: red; } </style> </head> <body> <h3>註冊頁面</h3> <div class="container"> <div class="row"> <div class="col-md-6 col-lg-offset-3"> <form id="form"> {% csrf_token %} {% for field in form %} <div class="form-group"> <label for="{{ field.auto_id }}">{{ field.label }}</label> {{ field }} <span class="error pull-right"></span> </div> {% endfor %} <div class="form-group"> <label for="avatar"> 頭像 <img id="avatar_img" width="60" height="60" src="/static/blog/img/default.png" alt=""> </label> <input type="file" id="avatar" name="avatar"> </div> <input type="button" class="btn btn-default reg_btn" value="submit"><span class="error"></span> </form> </div> </div> </div> <script> // 頭像預覽 $("#avatar").change(function () { // 獲取用戶選中的文件對象 var file_obj = $(this)[0].files[0]; // 獲取文件對象的路徑 var reader = new FileReader(); reader.readAsDataURL(file_obj); // 修改img的src屬性 ,src=文件對象的路徑 reader.onload = function () { $("#avatar_img").attr("src", reader.result) }; }); // 基於Ajax提交數據 $(".reg_btn").click(function () { //console.log($("#form").serializeArray()); var formdata = new FormData(); var request_data = $("#form").serializeArray(); $.each(request_data, function (index, data) { formdata.append(data.name, data.value) }); formdata.append("avatar", $("#avatar")[0].files[0]); $.ajax({ url: "", type: "post", contentType: false, processData: false, data: formdata, success: function (data) { //console.log(data); if (data.user) { // 註冊成功 location.href="/login/" } else { // 註冊失敗 //console.log(data.msg) // 清空錯誤信息 $("span.error").html(""); $(".form-group").removeClass("has-error"); // 展這次提交的錯誤信息! $.each(data.msg, function (field, error_list) { console.log(field, error_list); if (field=="__all__"){ $("#id_re_pwd").next().html(error_list[0]).parent().addClass("has-error"); } $("#id_" + field).next().html(error_list[0]); $("#id_" + field).parent().addClass("has-error"); }) } } }) }) </script> </body> </html>
你們仔細觀察上方代碼,在點擊頭像上傳圖片的時候,個人作法並非用什麼css定位之類的東西,而是直接用label自帶的屬性獲得點擊頭像就至關於上傳文件的效果。html
細節看圖python
僅僅如此!jquery
那如何實現頭像的實時預覽呢?ajax
猜測3步驟1,頭像應該是改變了 2,上傳文件以後應該拿到 該圖片的URL 3,將原有圖片src替換爲新圖片的src!django
onload是等待加載完成以後再去執行的內容!
下面就是forms組件了bootstrap
from django import forms from django.forms import widgets from blog.models import UserInfo from django.core.exceptions import NON_FIELD_ERRORS, ValidationError class UserForm(forms.Form): user=forms.CharField(max_length=32, error_messages={"required":"該字段不能爲空"}, label="用戶名", widget=widgets.TextInput(attrs={"class":"form-control"},) ) pwd=forms.CharField(max_length=32, label="密碼", widget=widgets.PasswordInput(attrs={"class":"form-control"},) ) re_pwd=forms.CharField(max_length=32, label="確認密碼", widget=widgets.PasswordInput(attrs={"class":"form-control"},) ) email=forms.EmailField(max_length=32, label="郵箱", widget=widgets.EmailInput(attrs={"class":"form-control"},) ) def clean_user(self): val=self.cleaned_data.get("user") user=UserInfo.objects.filter(username=val).first() if not user: return val else: raise ValidationError("該用戶已註冊!") def clean(self): pwd=self.cleaned_data.get("pwd") re_pwd=self.cleaned_data.get("re_pwd") if pwd and re_pwd: if pwd==re_pwd: return self.cleaned_data else: raise ValidationError("兩次密碼不一致!") else: return self.cleaned_data
當文件上傳的時候還須要在settings中配置靜態文件的路徑app
# 與用戶上傳相關的配置 MEDIA_ROOT=os.path.join(BASE_DIR,"media") MEDIA_URL="/media/"
而且還須要在URL中寫出,由於django沒有默認加。編輯器
re_path(r"media/(?P<path>.*)$",serve,{"document_root":settings.MEDIA_ROOT}), re_path('^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail),
在這裏須要注意ide
要先在URL中導入
from django.views.static import serve
在這裏上傳完整的URL配置
"""cnblog URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.0/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path,re_path from django.views.static import serve from blog import views from cnblog import settings from django.urls import include urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), path('logout/', views.logout), re_path('^$', views.index), path('get_validCode_img/', views.get_valid_code_img), path('register/', views.register), # 文本編輯器上傳圖片url path('upload/', views.upload), # 後臺管理url re_path("cn_backend/$",views.cn_backend), re_path("cn_backend/add_article/$",views.add_article), # 點贊 path("digg/",views.digg), # 評論 path("comment/",views.comment), # 獲取評論樹相關數據 path("get_comment_tree/",views.get_comment_tree), # media配置: re_path(r"media/(?P<path>.*)$",serve,{"document_root":settings.MEDIA_ROOT}), re_path('^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail), # article_detail(request,username="yuan","article_id":article_id) # 我的站點的跳轉 re_path('^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$', views.home_site), # home_site(reqeust,username="yuan",condition="tag",param="python") # 我的站點url re_path('^(?P<username>\w+)/$', views.home_site), # home_site(reqeust,username="yuan") ]
不能忘了導入,不然直接訪問靜態文件是找不到的