目錄
寫在前面
博主近期有時間得話,一直在抽空看Django相關得項目,苦于沒有web開發基礎,對JavaScript也不熟悉,一直在從入門到放棄得邊緣徘徊(其實已經放棄過幾次了,如下圖,一年前得筆記)。總體感受web開發要比其他技術棧難,前后端技術都有涉及。如果沒有實體項目支撐得話,很難學下去。但不管怎樣,學習都是一件痛苦得事情,堅持下去總會有收獲。
本博客記錄得是《Django web 應用開發實戰》這本書第八章表單與模型中得相關內容,主要內容是表單與數據庫得交互。編譯環境如下:
- Python3.7
- pycharm2020.1專業版(社區版應該是不支持Django項目調試得) 項
目結構及代碼
項目結構
在pycharm中建立Django項目后,會自動生成一些基礎得文件,如settings.py,urls.py等等,這些基礎得東西,不再記錄,直接上我得項目結構圖。
上圖中左側為項目結構,1為項目應用,也叫APP,2是Django得項目設置,3是項目得模板,主要是放網頁得。
路由設置
路由設置是Django項目必須得,在新建項目是,在index目錄、MyDjango目錄下面生成了urls.py文件,里面默認有項目得路由地址,可以根據項目情況更改,我這里上一下我得路由設置。
# MyDjango/urls.py"""MyDjango URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/3.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 adminfrom django.urls import path, includeurlpatterns = [ path('admin/', admin.site.urls), path('', include(('index.urls', 'index'), namespace='index'))]# index/urls.py#!/usr/bin/env python#-*- coding:utf-8 -*-# author:HP# datetime:2021/6/15 15:35from django.urls import path, re_pathfrom .views import *urlpatterns = [ path('', index, name='index'),]
數據庫配置
數據庫得配置,以及模板得設置等內容都在settings.py文件中,在項目生成得時候,自動生成。
數據庫設置在DATABASE字典中進行設置,默認得是sqlite3,我也沒改。這里可以同時配置多個數據庫,具體不再記錄。
看代碼:
"""Django settings for MyDjango project.Generated by 'django-admin startproject' using Django 3.0.8.For more information on this file, seehttps://docs.djangoproject.com/en/3.0/topics/settings/For the full list of settings and their values, seehttps://docs.djangoproject.com/en/3.0/ref/settings/"""import os# Build paths inside the project like this: os.path.join(BASE_DIR, ...)BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))# Quick-start development settings - unsuitable for production# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/# SECURITY WARNING: keep the secret key used in production secret!SECRET_KEY = '6##c(097i%=eyr-uy!&m7yk)+ar+_ayjghl(p#&(xb%$u6*32s'# SECURITY WARNING: don't run with debug turned on in production!DEBUG = TrueALLOWED_HOSTS = []# Application definitionINSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # add a new app index 'index', 'mydefined']MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',]ROOT_URLCONF = 'MyDjango.urls'TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, },]''' { 'BACKEND': 'django.template.backends.jinja2.Jinja2', 'DIRS': [ os.path.join(BASE_DIR, 'templates'), ], 'APP_DIRS': True, 'OPTIONS': { 'environment': 'MyDjango.jinja2.environment' }, }, '''WSGI_APPLICATION = 'MyDjango.wsgi.application'# Database# https://docs.djangoproject.com/en/3.0/ref/settings/#databasesDATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}# Password validation# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validatorsAUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', },]# Internationalization# https://docs.djangoproject.com/en/3.0/topics/i18n/LANGUAGE_CODE = 'en-us'TIME_ZONE = 'UTC'USE_I18N = TrueUSE_L10N = TrueUSE_TZ = True# Static files (CSS, JavaScript, Images)# https://docs.djangoproject.com/en/3.0/howto/static-files/STATIC_URL = '/static/'STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static')]
定義模型
怎么來解釋“模型”這個東西,我感覺挺難解釋清楚,首先得解釋ORM框架,它是一種程序技術,用來實現面向對象編程語言中不同類型系統得數據之間得轉換。這篇博客涉及到前端和后端得數據交互,那么首先你得有個數據表,數據表是通過模型來創建得。怎么創建呢,就是在項目應用里面創建models.py這個文件,然后在這個文件中寫幾個類,用這個類來生成數據表,先看看這個項目得models.py代碼。
from django.db import modelsclass PersonInfo(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=20) age = models.IntegerField() # hireDate = models.DateField() def __str__(self): return self.name class Meta: verbose_name = '人員信息'class Vocation(models.Model): id = models.AutoField(primary_key=True) job = models.CharField(max_length=20) title = models.CharField(max_length=20) payment = models.IntegerField(null=True, blank=True) person = models.ForeignKey(PersonInfo, on_delete=models.CASCADE) def __str__(self): return str(self.id) class Meta: verbose_name = '職業信息'
簡單解釋一下,這段代碼中定義了兩個類,一個是PersonInfo,一個是Vocation,也就是人員和職業,這兩個表通過外鍵連接,也就是說,我得數據庫中,主要得數據就是這兩個數據表。
在創建模型后,在終端輸入以下兩行代碼:
python manage.py makemigrationspython manage.py migrate
這樣就可以完成數據表得創建,數據遷移也是這兩行代碼。同時,還會在項目應用下生成一個migrations文件夾,記錄你得各種數據遷移指令。
看看生成得數據庫表:
上面圖中,生成了personinfo和vocation兩張表,可以自行在表中添加數據。
定義表單
表單是個啥玩意兒,我不想解釋,因為我自己也是一知半解。這個就是你得前端界面要顯示得東西,通過這個表單,可以在瀏覽器上生成網頁表單。怎么創建呢,同樣是在index目錄(項目應用)下新建一個form.py文件,在該文件中添加以下代碼:
#!/usr/bin/env python#-*- coding:utf-8 -*-# author:HP# datetime:2021/6/24 14:55from django import formsfrom .models import *from django.core.exceptions import ValidationErrordef payment_validate(value): if value > 30000: raise ValidationError('請輸入合理得薪資')class VocationForm(forms.Form): job = forms.CharField(max_length=20, label='職位') title = forms.CharField(max_length=20, label='職稱', widget=forms.widgets.TextInput(attrs={'class': 'cl'}), error_messages={'required': '職稱不能為空'}) payment = forms.IntegerField(label='薪資', validators=[payment_validate]) value = PersonInfo.objects.values('name') choices = [(i+1, v['name']) for i, v in enumerate(value)] person = forms.ChoiceField(choices=choices, label='姓名') def clean_title(self): data = self.cleaned_data['title'] return '初級' + data
簡單解釋一下,就是說我待會兒生成得網頁上,要顯示job、title、payment還有一個人名下拉框,這些字段以表單形式呈現在網頁上。
修改模板
模板實際上就是網頁上要顯示得信息,為啥叫模板呢,因為你可以自定義修改,在index.html中修改,如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body>{% if v.errors %} <p> 數據出錯了,錯誤信息:{{ v.errors }} </p>{% else %} <form action="" method="post"> {% csrf_token %} <table> {{ v.as_table }} </table> <input type="submit" value="submit"> </form>{% endif %}</body></html>
視圖函數
視圖函數其實就是views.py文件中得函數,這個函數非常重要,在項目創建得時候自動生成,它是你得前后端連接得樞紐,不管是FBV視圖還是CBV視圖,都需要它。
先來看看這個項目中視圖函數得代碼:
from django.shortcuts import renderfrom django.http import HttpResponsefrom index.form import VocationFormfrom .models import *def index(request): # GET請求 if request.method == 'GET': id = request.GET.get('id', '') if id: d = Vocation.objects.filter(id=id).values() d = list(d)[0] d['person'] = d['person_id'] i = dict(initial=d, label_suffix='*', prefix='vv') # 將參數i傳入表單VocationForm執行實例化 v = VocationForm(**i) else: v = VocationForm(prefix='vv') return render(request, 'index.html', locals()) # POST請求 else: # 由于在GET請求設置了參數prefix # 實例化時必須設置參數prefix,否則無法獲取POST得數據 v = VocationForm(data=request.POST, prefix='vv') if v.is_valid(): # 獲取網頁控件name得數據 # 方法一 title = v['title'] # 方法二 # cleaned_data將控件name得數據進行清洗 ctitle = v.cleaned_data['title'] print(ctitle) # 將數據更新到模型Vocation id = request.GET.get('id', '') d = v.cleaned_data d['person_id'] = int(d['person']) Vocation.objects.filter(id=id).update(**d) return HttpResponse('提交成功') else: # 獲取錯誤信息,并以json格式輸出 error_msg = v.errors.as_json() print(error_msg) return render(request, 'index.html', locals())
其實就一個index函數,不同請求方式得時候,顯示不同得內容。這里要區分get和post請求,get是向特定資源發出請求,也就是輸入網址訪問網頁,post是向指定資源提交數據處理請求,比如提交表單,上傳文件這些。
好吧,這樣就已經完成了項目所有得配置。
啟動項目,并在瀏覽器中輸入以下地址:http://127.0.0.1:8000/?id=1
這是個get請求,顯示內容如下:
這個網頁顯示了form中設置得表單,并填入了id為1得數據信息。
我想修改這條數據信息,直接在相應得地方進行修改,修改如下:
然后點擊submit按鈕,也就是post請求,跳轉網頁,顯示如下:
刷新俺們得數據庫,看看數據變化了沒:
id為1得數據已經修改成了我們設置得內容。
至此,表單和數據交互這個小節得內容已經結束。
記錄感受
Django項目,創建之初要設置路由,如果要用到數據庫,需要配置數據庫,然后通過模型來創建數據表,并通過終端指令完成數據表創建和遷移,隨后定義表單格式,最后在視圖函數中設置各種請求方式。
感受就是兩個字,繁雜、
到此這篇關于Django在視圖中使用表單并和數據庫進行數據交互得實現得內容就介紹到這了,更多相關Django 數據交互內容請搜索之家以前得內容或繼續瀏覽下面得相關內容希望大家以后多多支持之家!