Python Django框架中表單的用法詳解

Django保證表單的正確顯示需要添加CSRF(防止網站跨站請求偽造而默認開啟的一種保護方式),在<form></form>之間添加

{% csrf_token %}

在項目settings.py中 * ‘django.middleware.csrf.CsrfViewMiddleware’, * 引入,如果沒有此中間件,手動添加。

文件上傳

首次打開路徑是GET請求,如果點擊上傳是POST請求,如果文件內容不為空,則上傳文件,上傳路徑為主項目下的 media/uploads/,如果路徑不存在則新建。open(os.path.join(path + myFile.name), ‘wb+’) 二進制讀寫打開對應文件,chunks()將文件分塊讀寫。

def upload_file(request):
    if request.method == "GET":
        return render(request, 'app1/upload.html')
    if request.method == "POST":
        myFile = request.FILES.get("myfile", None)
        if myFile:
            path = 'media/uploads/'
            if not os.path.exists(path):
                os.makedirs(path)
            dest = open(os.path.join(path + myFile.name), 'wb+')
            for chunk in myFile.chunks():
                dest.write(chunk)
            dest.close()
            return HttpResponse("上傳完成")
        else:
            return HttpResponse("沒有上傳文件")

添加路由。

文件已經上傳成功。

Form表單

如下新建一個form.py寫入如下代碼

from django import forms

class UserInfoForm(forms.Form):
    '''用戶狀態'''
    STATUS = ((None, '請選擇'), (0, '正常'), (1, '無效'),)
    username = forms.CharField(label="用戶名稱", min_length=6, widget=forms.widgets.TextInput(
        attrs={'class': 'form-control', 'placeholder': '請輸入用戶名稱'}
    ))
    password = forms.CharField(label="密碼", min_length=6, max_length=10, widget=forms.widgets.PasswordInput(
        attrs={'class': 'password'}, render_value=True
    ))
    age = forms.IntegerField(label="年齡", initial=1)
    mobile = forms.IntegerField(label="手機號碼")
    status = forms.ChoiceField(label="用戶狀態", choices=STATUS)
    createdate = forms.DateTimeField(label="創建時間", required=False)

表單字段

表單字段 說明
CharField 文本輸入
InterField/FloatField/DecimalField 數值輸入
ChoiceField 選擇輸入框 choices指定下拉列表
FileField 文件
BooleanField 復選框
DateField/DateTimeField/TimeField 時間輸入框,可以設置輸入格式 input_format=[“%Y-%m-%d %H:%M”]
EmailField 郵件輸入框
URLField 路勁輸入框
ModelChoiceField 從數據庫獲取下拉列表

字段參數

字段 說明
label label標簽
label_suffix Label標簽統一後綴信息
initial 初始值
help_text 字段描述信息
error_messages 字段描述信息
validators 驗證規則
required 是否必須
disabled 字段是否可編輯
widget 指定HTML樣式

widget參數

參數 說明
PasswordInput 密碼輸入框
HiddenInput 隱藏元素
Textarea 文本域
CheckboxInput 復選框
FileInput 文件輸入框
RadioSelect 單選按鈕
DateTimeInput 時間輸入框
Select 下拉列表
SelectMuitiple 多選框

配置視圖和路徑顯示對應表單

app1下的views.py

def userinfo_form(request):
    if request.method == "GET":
        myForm = UserInfoForm()

        return render(request, 'app1/userinfo.html', {'form_obj': myForm})

userinfo.html

<html>
  <head></head>
  <body>
    <form action="" method="POST">
      {% csrf_token %} {{ form_obj.as_p }}
      <input type="submit" value="提交" />
    </form>
  </body>
</html>

  • as_p 為表單提供<p>標簽
  • as_table 為表單提供<table>標簽
  • as_ui 為表單提供<ui>標簽

以上用瞭as_p,故源代碼顯示p標簽。

表單的驗證

  • is_valid() 驗證表單數據是否合法
  • cleaned_data 獲取表單通過驗證的數據
  • errors 表單驗證的錯誤信息

在form中添加如下代碼

class UserInfoForm__Msg(forms.Form):
    '''用戶狀態'''
    STATUS = ((None, '請選擇'), (0, '正常'), (1, '無效'),)
    username = forms.CharField(label="用戶名稱", min_length=6, widget=forms.widgets.TextInput(
        attrs={'class': 'form-control', 'placeholder': '請輸入用戶名稱'}
    ), error_messages={
        'required': '用戶姓名不能為空', 'min_length': '長度不能少於6位', 'invalid': '不能含有特殊字符'
    })
    password = forms.CharField(label="密碼", min_length=6, max_length=10, widget=forms.widgets.PasswordInput(
        attrs={'class': 'password'}, render_value=True
    ), error_messages={
        'required': '密碼不能為空', 'min_length': '密碼不能少於6位', 'max_length': '密碼不能多餘10位',
    })
    age = forms.IntegerField(label="年齡", initial=1, validators=[age_validate], error_messages={
        'required': '年齡不能為空',
    })
    mobile = forms.IntegerField(label="手機號碼", validators=[mobile_validate], error_messages={
        'required': '手機號碼不能為空',
    })
    status = forms.ChoiceField(label="用戶狀態", choices=STATUS, error_messages={
        'required': '用戶狀態不能為空',
    })
    createdate = forms.DateTimeField(label="創建時間", required=False)
  • required 為空的時候的錯誤信息
  • invalid 格式驗證錯誤的信息
  • min_length和max_length 長度不在設定的范圍的錯誤信息

添加視圖

def userinfo_form_msg(request):
    if request.method == "GET":
        myForm = UserInfoForm__Msg()
        return render(request, 'app1/userinfoform.html', {'form_obj': myForm})
    else:
        f = UserInfoForm__Msg(request.POST)
        if f.is_valid():
            print(f.cleaned_data['username'])
        else:
            errors = f.errors
            print(errors)
            return render(request, 'app1/userinfoform.html', {'form_obj': f, 'errors': errors})
        return render(request, 'app1/userinfoform.html', {'form_obj': f})

模板文件

<form action="" method="POST" novalidate>
  {% csrf_token %}
  <p>
    {{ form_obj.username.label }}:{{ form_obj.username }} {{ errors.username.0 }}
  </p>
  <p>{{ form_obj.password}}{{ errors.password.0 }}</p>
  <p>{{ form_obj.status.label }}:{{ form_obj.status }} {{ errors.status.0 }}</p>
  <p>{{ form_obj.age.label }}:{{ form_obj.age }} {{ errors.age.0 }}</p>
  <p>{{ form_obj.mobile.label }}:{{ form_obj.mobile }} {{ errors.mobile.0 }}</p>
  錯誤信息匯總: {{ errors }}
  <input type="submit" value="提交" />
</form>

這裡還添加瞭表單的自我格式驗證,獲取表單的數據

  • f.clean() 獲取全部數據
  • f.clean_date[] 獲取對應值的數據
  • f.data 獲取全部數據

表單模型文件上傳例子

模板文件:upload_form.html

<form enctype="multipart/form-data" action="" method="post">
  {% csrf_token %} {{ form_obj.as_p }}
  <br />
  <input type="submit" value="文件上傳" />
  <img src="media/uploads/{{%20user.heading%20}}"
</form>

模型文件

在models.py中添加模型,這裡沒有主鍵默認會生成id的主鍵

class ImgFile(models.Model):
    name = models.CharField(verbose_name='用戶名稱', max_length=300, default="")
    heading = models.FileField(verbose_name='文件名', upload_to='media/uploads/')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = ' 用戶頭像信息'
        db_table = 'user_img'

表單模型 form.py

class ImgFileForm(forms.Form):
    name = forms.CharField()
    heading = forms.FileField()

視圖模型

如果上傳瞭文件,將文件保存在對應的目錄下,並返回文件的信息。

def ingfileform(request):
    if request.method == "GET":
        f = ImgFileForm()
        return render(request, 'app1/upload_form.html', {'form_obj': f})
    else:
        f = ImgFileForm(request.POST, request.FILES)
        if f.is_valid():
            name = f.cleaned_data['name']
            heading = f.cleaned_data['heading']
            path = 'media/uploads/'
            if not os.path.exists(path):
                os.makedirs(path)
            dest = open(os.path.join(path + heading.name), 'wb+')
            for chunk in heading.chunks():
                dest.write(chunk)
            dest.close()

            userimg = ImgFile()
            userimg.name = name
            userimg.heading = heading
            userimg.save()
            print('上傳成功')
            return render(request, 'app1/upload_form.html', {'form_obj': f, 'user': userimg})
        else:
            print(f.errors)

路由

re_path 配置瞭可以直接在瀏覽器訪問對應的文件,

from django.urls import path, include, re_path
from django.views.static import serve
from mywed import settings
    path('app1/userimg/', views.ingfileform),
    re_path('media/uploads/(?P<path>.*)', serve,
            {"document_root": settings.MEDIA_ROOT}),

settings.py

這裡路徑在項目文件中設置便於統一,在實際的應用中也應該多在公共文件中設置

MEDIA_URL = "media/uploads/"
MEDIA_ROOT = os.path.join(MEDIA_URL, "")

db中也登陸瞭對應的信息

模型表單

Django提供瞭ModelForm可以直接和模型關聯,省略瞭Form表單中定義的操作。

AJAX

模板文件,為瞭能夠正常的訪問,必須添加csrfmiddlewaretoken或者在視圖函數中註釋@csrf_exempt,建議使用第一種方式

用戶名:<input type="text" id="username"></input>
密碼:<input type="password" id="password"></input>
{% csrf_token %}
<button id="submit">提交</button>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>

$("#submit").click(function(){
    var csrf = $('input[name="csrfmiddlewaretoken"]').val();
    $.ajax({
      url: '/app1/ajax_login_data',
      type: "post",
      data: {
        'username': $("#username").val(),
        'password': $("#password").val(),
        'csrfmiddlewaretoken': csrf
      },
      success: function(data){
        console.log(data)
      },
      error: function(jqXHR, textStatus, err){
        console.log(arguments);
      }
    });
  }); 
</script>

視圖文件

from django.views.decorators.csrf import csrf_exempt
def ajax_login(request):
    return render(request, 'app1/ajax.html')


# @csrf_exempt
def ajax_login_data(request):

    if request.method == "GET":
        HttpResponse("內部自己的url")
    username = request.POST.get('username')
    password = request.POST.get('password')
    print(username)
    if username == 'admin' and password == '123456':
        return JsonResponse({
            'code': 1,
            'msg': "登陸成功"
        })
    else:
        print("222")
        return JsonResponse({
            'code': 0,
            'msg': "登陸失敗"

這裡使用的是網上的jquery地址,也可在settings.py匹配如下,在網站根目錄中創建static目錄,放入jquery文件。

<script src=“/statics/jquery.min.js”></script>

STATIC_URL = '/statics/'

​​​​​​​STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "statics"),
]

以上就是Python Django框架中表單的用法詳解的詳細內容,更多關於Python Django表單的資料請關註WalkonNet其它相關文章!

推薦閱讀: