首頁 > 軟體

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

2022-06-24 14:05:30

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從資料庫獲取下拉選單

欄位引數

欄位說明
labellabel標籤
label_suffixLabel標籤統一字尾資訊
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/{{ user.heading }}"
</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表單的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com