djagon實戰form數據庫等操作
項目需求分析
通過form表單的方式,來實現以下幾個功能
1、html標簽的自動生成
2、上次輸入數據的保留
3、輸入數據的驗證
代碼實施
數據庫代碼
from django.db import models class Classes(models.Model): title = models.CharField(max_length=32) class Student(models.Model): sname = models.CharField(max_length=32) email = models.CharField(max_length=32) age = models.IntegerField() cls = models.ForeignKey(‘Classes‘,on_delete=models.CASCADE) class Teacher(models.Model): tname = models.CharField(max_length=32) c2t = models.ManyToManyField(‘Classes‘)
數據庫報錯‘on_delete‘
Djiango的時候發現執行mange.py makemigrations 和 migrate是會報錯,少位置參數on_delete,查了一下是因為指定外鍵的方式不對,改一下就OK了。
一對多設計 多方持有一方的外鍵
所以解決方法是:
cls = models.ForeignKey(‘Classes‘)
添加字段變成
cls = models.ForeignKey(‘Classes‘,on_delete=models.CASCADE)
班級管理
由於不小心把django升級到了2.0版本,在做路由的時候發現出現了問題,下面有記錄。2.0是咱們為python3.x出的,先用用看
1、班級的列表
2、班級的增加
3、班級的編輯
班級的路由url
from django.contrib import admin from django.urls import path,re_path from clsmanagent import views from django.conf.urls import url urlpatterns = [ path(‘class_list/‘, views.class_list), path(‘add_class/‘, views.add_class), path(‘edit_class/<int:nid>/‘, views.edit_class),
班級管理列表
視圖文件py
from django.shortcuts import render,redirect,HttpResponse
from django.forms import Form, fields,widgets
from clsmanagent import models
# 班級form驗證
class ClassForm(Form):
title = fields.RegexField(‘全棧\d+‘,label=‘班級名稱‘)
# 班級信息
def class_list(request):
# if request.method == "GET":
obj = models.Classes.objects.all()
return render(request, ‘classlist.html‘, {‘obj‘: obj})
班級的列表的html文件
<h2>班級列表</h2>
<hr>
<span><a href="/add_class/">添加班級</a></span>
{#<form action="/class_list/" method="post">#}
{# {% csrf_token %}#}
<ul>
{% for cls_list in obj %}
<li>{{ cls_list.title }}<a href="/edit_class/{{ cls_list.id }}/">編輯</a></li>
{% endfor %}
</ul>
{#</form>#}
班級增加功能
增加功能視圖文件
#添加班級
def add_class(request):
if request.method == "GET":
obj = ClassForm()
return render(request,‘addclass.html‘,{‘obj‘:obj})
else:
obj = ClassForm(request.POST)
if obj.is_valid():
models.Classes.objects.create(**obj.cleaned_data)
return redirect(‘/class_list/‘)
return render(request, ‘addclass.html‘, {‘obj‘: obj})
增加班級的html代碼
<form action="/add_class/" method="post">
{% csrf_token %}
<p>
{# {{ obj.as_p }}#}
{{ obj.title }} {{ obj.errors.title.0 }}
</p>
<p>
<input type="submit" value="提交">
</p>
</form>
編輯班級
編輯班級視圖文件
def edit_class(request,nid):
if request.method == "GET":
cls_info = models.Classes.objects.filter(id=nid).first()
print(cls_info)
obj = ClassForm(initial={‘title‘:cls_info.title})
return render(request,‘editclass.html‘,{‘obj‘:obj,‘nid‘:nid})
else:
obj = ClassForm(request.POST)
if obj.is_valid():
models.Classes.objects.filter(id=nid).update(**obj.cleaned_data)
return redirect(‘/class_list/‘)
return render(request,‘editclass.html‘,{‘obj‘:obj,‘nid‘:nid})
編輯班級的html代碼
<body>
<h2>編輯班級</h2>
<hr>
<form action="/edit_class/{{ nid }}/" method="post">
{% csrf_token %}
<p>
{{ obj.title }}{{ obj.errors.title.0 }}
</p>
<input type="submit" value="提交">
</form>
學生表功能
功能和班級功能一樣,這裏就把視圖函數全部放到一起
#學生列表
def student_list(request):
stu_list = models.Student.objects.all()
return render(request,‘studentlist.html‘,{‘stu_list‘:stu_list})
#添加學生
##創建學生的Form條件驗證
class StuForm(Form):
sname = fields.CharField(min_length=2,max_length=6,label=‘學生姓名‘)
email = fields.EmailField()
age = fields.IntegerField()
cls_id = fields.IntegerField(
widget=widgets.Select(choices=models.Classes.objects.values_list(‘id‘,‘title‘))#把班級變成下拉框,這裏django會自動給我們記錄select的value,不需要我們自己來操心
)
def add_stu(request):
if request.method == "GET":
obj = StuForm()
return render(request,‘addstudent.html‘,{‘obj‘:obj})
else:
obj = StuForm(request.POST)
if obj.is_valid():
models.Student.objects.create(**obj.cleaned_data)
return redirect(‘/student_list/‘)
return render(request,‘addstudent.html‘,{‘obj‘:obj})
#編輯學生
def edit_stu(request,nid):
if request.method == "GET":
row = models.Student.objects.filter(id=nid).values(‘sname‘,‘email‘,‘age‘,‘cls_id‘).first()#讓他變成字典的類型可以傳參到下面的form裏面,因為我們知道表達裏面的data和initial後面都是一個字典類型
obj = StuForm(row)
return render(request,‘editstudent.html‘,{‘obj‘:obj,‘nid‘:nid})
else:
obj = StuForm(request.POST)
if obj.is_valid():
models.Student.objects.filter(id=nid).update(**obj.cleaned_data)#參數我一個字典
return redirect(‘/student_list/‘)
return render(request,‘editstudent.html‘,{‘obj‘:obj,‘nid‘:nid})
學生列表html代碼
<h2>學生列表</h2>
<hr>
<a href="/add_stu/">添加學生</a>
<ul>
{% for stu in stu_list %}
<li>{{ stu.sname }}-{{ stu.age }}-{{ stu.email }}-{{ stu.cls_id }}<a href="/edit_stu/{{ stu.id }}/">編輯</a></li>
{% endfor %}
</ul>
增加學生html代碼
<form action="/add_stu/" method="post" novalidate>
{% csrf_token %}
<h2>添加學生</h2>
<hr>
<p>{{ obj.sname }}{{ obj.errors.sname.0 }}</p>
<p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
<p>{{ obj.age }}{{ obj.errors.age.0 }}</p>
<p>{{ obj.cls_id }}{{ obj.errors.cls_id.0 }}</p>
<input type="submit" value="提交">
</form>
編輯學生html代碼
<h2>編輯學生信息</h2>
<hr>
<form action="/edit_stu/{{ nid }}" method="post">
{% csrf_token %}
<p>{{ obj.sname }}</p>
<p>{{ obj.email }}</p>
<p>{{ obj.age }}</p>
<p>{{ obj.cls_id }}</p>
<input type="submit" value="提交">
</form>
urls故障
https://docs.djangoproject.com/en/2.0/intro/tutorial02/
django2.0版本主要更新了urls,url變成了path,在使用r‘^edit_class/(\d+)/‘, views.edit_class),
路由的時候,發現報錯404不能找到路徑。經過查看文檔發現2.0v版本以後url變成了path,而path的規則變成了如下:
<ul>
{% for cls_list in obj %}
<li>{{ cls_list.title }}<a href="/edit_class/{{ cls_list.id }}/">編輯</a></li>
{% endfor %}
</ul>
from django.urls import path
from . import views
urlpatterns = [
path(‘edit_class/<int:nid>/‘, views.edit_class),
]
這裏把傳入的參數會變成指定的,不需要(\d+/)了,
轉換格式類型
說明
Str
匹配除分隔符(/)外的非空字符,默認類型<year>等價於<str:year>
Int
匹配0和正整數
Slug
匹配字母、數字、橫杠、下劃線組成的字符串,str的子集
Uuid
匹配格式化的UUID,如075194d3-6885-417e-a8a8-6c931e272f00
path
匹配任何非空字符串,包括路徑分隔符,是全集
djagon實戰form數據庫等操作