# 建立部門表單校驗html
class DepartmentForm(forms.ModelForm): class Meta: model = models.Department #關聯到Models中的表名Department fields = '__all__' #獲取Department表中的全部對象,也能夠寫成列表['depName','depDes'],指定要獲取的對象,並且是有順序的 labels = { 'depName': '部門名稱', 'depDes': '職責描述', } widgets = { #設置插件,type類型和類名等屬性 'depName': forms.TextInput(attrs={'class': 'form-control','placeholder':'請輸入部門名稱'}), 'depDes': forms.TextInput(attrs={'class': 'form-control','placeholder':'請輸入部門職責描述'}), }
class Meta:下經常使用參數:前端
model = models.Department # 對應的Model中的類
fields = "__all__" # 字段,若是是__all__,就是表示列出全部的字段,也能夠寫成列表['title','price'],指定要獲取的對象
exclude = None # 排除的字段
labels = None # 提示信息
help_texts = None # 幫助提示信息
widgets = None # 自定義插件,form組件裏是widget,ModelForm組件裏是widgets
error_messages = None # 自定義錯誤信息django
其中label屬性能夠不在ModelForm這裏面寫,也能夠在models.py中的Depart表中各個對象定義verbose_name屬性值,用於非ForeignKey對象,
推薦這種寫法,在Admin系統中也能夠顯示這裏定義的verbose_name值bootstrap
class Depart(models.Model): depName = models.TextField(max_length=32, verbose_name='部門名稱') depDes = models.TextField(max_length=64, black=True, null=True, verbose_name='職責描述')
可經過重寫ModelForm類的init方法來實現。ide
# 建立部門表單校驗函數
class DepartmentForm(forms.ModelForm): depName = forms.TextField(validators=[],) #若是depName字段存在,就表明重寫這個字段 count = forms.TextField(validators=[],) #若是count字段不存在,就表明新增這個字段,models文件中不存在這個字段 class Meta: model = models.Department #model和fields都是固定寫法,不能寫 fields = '__all__' labels = { 'depName': '部門名稱', 'depDes': '職責描述', } widgets = { 'depName': forms.TextInput(attrs={'placeholder':'請輸入部門名稱'}), 'depDes': forms.TextInput(attrs={'placeholder':'請輸入部門職責描述'}), 'purchase_date': forms.widgets.DateInput(attrs={'type': 'date'}), 'expiration_date': forms.widgets.DateInput(attrs={'type': 'date'}), } error_messages = { #這裏的error_messages只能寫默認存在的校驗字段 'depName':{ 'required':'不能爲空' } } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) for field in self.fields.values(): field.widget.attrs.update({'class': 'form-control'}) class DepartAdd(View): def get(self, request): form_obj = DepartmentForm() return render(request, 'departadd.html', {'form_obj': form_obj}) def post(self, request): form_obj = DepartmentForm(request.POST) print(form_obj) if form_obj.is_valid(): # models.Department.objects.create(**form_obj.cleaned_data) form_obj.save() #直接save()方法就能夠保存 return redirect(reverse('departList'))
部門添加oop
def depart_add(request): form_obj = departForm.DepartForm() if request.method == 'POST': form_obj = departForm.DepartForm(request.POST) if form_obj.is_valid(): form_obj.save() return redirect(reverse('depart_list')) return render(request, 'depart/depart_add.html', {'form_obj': form_obj})
部門修改post
def depart_edit(request, pk): form_edit = models.Depart.objects.filter(pk=pk).first() form_obj = departForm.DepartForm(instance=form_edit) if request.method == 'POST': form_obj = departForm.DepartForm(request.POST, instance=form_edit) #這裏要將當前對象做爲一個實例傳給ModelForm # 若是沒有修改,則不須要校驗 depart_name_new = request.POST.get('depart_name', None) if form_edit.depart_name == depart_name_new: # 部門描述不須要校驗,直接更新保存 form_edit.depart_desc = request.POST.get('depart_desc', None) form_edit.save() return redirect(reverse('depart_list')) # 若是修改了值,就調用DepartForm校驗,注意用instance表示將當前對象傳給Modelform校驗,模板中字段仍然能夠自動生成 elif form_obj.is_valid(): form_obj.save() return redirect(reverse('depart_list')) return render(request, 'depart/depart_edit.html', {'form_edit': form_edit, 'form_obj': form_obj})
前端頁面ui
展現頁面depart_list.htmlurl
<table class="form-horizontal table table-bordered" style="margin-top: 10px"> <thead> <tr> <th>ID</th> <th>用戶名稱</th> <th>密碼</th> <th>所屬部門</th> <th>操做</th> </tr> </thead> <tbody> {% for user in user_all %} <tr> <td>{{ forloop.counter }}</td> <td>{{ user.username }}</td> <td>{{ user.pwd }}</td> {# <td>{{ user.depart.depart_name}}</td>#} #這裏能夠經過depart外鍵.depart_name來獲取部門名稱進行前端頁面顯示 <td>{{ user.depart }}</td> #也能夠經過在models.py中給Depart類寫__str__方法,這裏就不須要用點方法了 <td> <a href="{% url 'user_edit' user.pk %}"><i class="fa fa-edit fa-2x"></i></a> <a class="del" del_obj="user" del_id="{{ user.pk }}"><i class="fa fa-trash-o fa-2x" style="cursor: pointer;"></i></a> </td> </tr> {% endfor %} </tbody> </table>
修改頁面depart_edit.html
<form action="" method="post" class="form-horizontal"> {% csrf_token %} <div class="form-group {% if form_obj.depName.errors %}has-error{% endif %}"> <label for="{{ form_obj.depName.id_for_label }}" class="col-lg-2 control-label">{{ form_obj.depName.label }}</label> <div class="col-lg-6"> {{ form_obj.depName }} </div> <span class="help-block">{{ form_obj.errors.0 }}</span> </div> bootstrape樣式中使用has-error和help-block類渲染錯誤提示效果
models.py
from django.db import models # Create your models here. class Depart(models.Model): depart_name = models.CharField(max_length=32, verbose_name='部門名稱') depart_desc = models.CharField(max_length=64, verbose_name='部門描述') #經過寫__str__方法,前端直接調用depart對象時就能夠直接獲取到depart_name的值了 def __str__(self): return self.depart_name class User(models.Model): username = models.CharField(max_length=32, verbose_name='用戶名') pwd = models.CharField(max_length=32, verbose_name='密碼') depart = models.ForeignKey(to='Depart', verbose_name='所屬部門')
一、depart_all.html模板代碼合併
未合併寫法,寫了多個form-group,重複
<form action="" method="post" class="form-horizontal" novalidate> {% csrf_token %} <div class="form-group {% if form_obj.depart_name.errors %}has-error{% endif %}"> <label for="{{ form_obj.depart_name.id_for_label }}" class="col-lg-2 control-label"> {{ form_obj.depart_name.label }} </label> <div class="col-lg-6"> {{ form_obj.depart_name }} <span class="help-block">{{ form_obj.depart_name.errors.0 }}</span> </div> </div> <div class="form-group {% if form_obj.depart_desc.errors %}has-error{% endif %}"> <label for="{{ form_obj.depart_desc.id_for_label}}" class="col-lg-2 control-label "> {{ form_obj.depart_desc.label }} </label> <div class="col-lg-6"> {{ form_obj.depart_desc }} <span class="help-block">{{ form_obj.depart_desc.errors.0 }}</span> </div> </div> <div class="form-group"> <div class="col-lg-10 col-lg-offset-2"> <button class="btn btn-primary">提交</button> </div> </div> </form>
合併寫法
<form action="" method="post" class="form-horizontal" novalidate> {% csrf_token %} {#須要渲染多個form-group, 可使用for循環避免從新編寫,將form_obj.depart_name和form_obj.depart_desc改爲field便可#} {% for field in form_obj %} <div class="form-group {% if field.errors %}has-error{% endif %}"> <label for="{{ field.id_for_label }}" class="col-lg-2 control-label"> {{ field.label }} </label> <div class="col-lg-6"> {{ field }} <span class="help-block">{{ field.errors.0 }}</span> </div> </div> {% endfor %} <div class="form-group"> <div class="col-lg-10 col-lg-offset-2"> <button class="btn btn-primary">提交</button> </div> </div> </form>
二、views.py視圖代碼合併
未合併寫法
urls.py url(r'^user/add/$', user.user_add, name='user_add'), url(r'^user/edit/(\d+)/$', user.user_edit, name='user_edit'), views.py #用戶添加函數 def user_add(request): form_obj = userForm.UserForm() if request.method == 'POST': form_obj = userForm.UserForm(request.POST) if form_obj.is_valid(): form_obj.save() return redirect(reverse('user_list')) return render(request, 'user/user_add.html', {'form_obj': form_obj}) #用戶編輯函數 def user_edit(request, pk): obj = models.User.objects.filter(pk=pk).first() form_obj = userForm.UserForm(instance=obj) if request.method == 'POST': form_obj = userForm.UserForm(request.POST, instance=obj) # 若是未修改原值,則不校驗 if request.POST.get('username', None) == obj.username: obj.pwd = request.POST.get('pwd', None) obj.gender = request.POST.get('gender', None) # depart不能直接保存爲request.POST.get('depart',None),由於depart是一個外鍵,須要保存Depart的一個實例 obj.depart = models.Depart.objects.filter(pk=request.POST.get('depart', None)).first() obj.save() # 這裏先建立用戶的時候校驗密碼不能爲空,可是修改用戶時沒有校驗密碼是否爲空 return redirect(reverse('user_list')) # 修改了原值,則進行校驗 elif form_obj.is_valid(): form_obj.save() return redirect(reverse('user_list')) return render(request, 'user/user_edit.html', {'form_obj': form_obj})
將用戶添加函數和用戶編輯函數合併編寫
將urls中函數方法統一寫成user_change,在views中只須要寫一個user_change函數包含用戶添加和編輯功能。 urls.py url(r'^user/add/$', user.user_change, name='user_add'), url(r'^user/edit/(\d+)/$', user.user_change, name='user_edit'), views.py 因爲用戶添加和編輯函數邏輯類似,能夠合併編寫 區別就是編輯函數須要傳入pk值,而添加函數不須要傳入pk值,因此設置pk=None默認爲空 其餘代碼基本相同 def user_change(request, pk=None): #若是是添加方法,則obj爲空 obj = models.User.objects.filter(pk=pk).first() form_obj = userForm.UserForm(instance=obj) if request.method == 'POST': form_obj = userForm.UserForm(request.POST, instance=obj) if obj: # 若是未修改username原值,則不校驗 if request.POST.get('username', None) == obj.username: obj.pwd = Md5(request.POST.get('pwd', None)).md5 obj.gender = request.POST.get('gender', None) # depart不能直接保存爲request.POST.get('depart',None),由於depart是一個外鍵,須要保存Depart的一個實例 obj.depart = models.Depart.objects.filter(pk=request.POST.get('depart', None)).first() obj.save() # 這裏先建立用戶的時候校驗密碼不能爲空,可是修改用戶時沒有校驗密碼是否爲空 return redirect(reverse('user_list')) # 修改了原值,則進行校驗 elif form_obj.is_valid(): form_obj.save() return redirect(reverse('user_list')) return render(request, 'user/user_edit.html', {'form_obj': form_obj})