Django中的Form(二)

 

一、保存用户输入内容

 如果用户输入一张表单提交后出现错误时,会出现重现填写的情况。我们可以把用户输入的信息保存下来,并返回到前台页面,这样用户就无需再次输入。

views.py

 1 # coding:utf-8
 2 from django.shortcuts import render, HttpResponse, redirect
 3 from app01.forms import account as Account_Forms
 4 
 5 
 6 def login(request):
 7 
 8     obj = Account_Forms.UserInfo(request.POST)  #将用户输入的内容添加到form的对象中
 9     if request.method == 'POST':
10         return render(request, 'account/login.html', {'obj': obj})   #将用户输入的内容返回到前台页面
11     return render(request, 'account/login.html', {'obj': obj})

 

forms.py

1 from django import forms
2 
3 
4 class UserInfo(forms.Form):
5     username = forms.CharField()
6     password = forms.CharField(widget=forms.PasswordInput())

 

html文件

 1 {% load staticfiles %}
 2 <!DOCTYPE html>
 3 <html lang="en">
 4 <head>
 5     <meta charset="UTF-8">
 6     <title></title>
 7 </head>
 8 <body>
 9 
10 <form action="/login/" method="post">
11     <p>{{ obj.username }}</p>
12     <p>{{ obj.password }}</p>
13     <input type="submit" value="submit">
14 </form>
15 
16 {#<script type="text/javascript" src="{{ STATIC_URL }}/js/jquery-2.1.4.min.js">#}
17 <script type="text/javascript" src="{% static "js/jquery-2.1.4.min.js" %}"></script>
18 </body>
19 </html>

 

二、生成动态的select

 form中可以再前端生成select,select一般会分为两类:1、内容不变的数据。 2、从数据库或者文件中提取的经常发生改变的数据。1的实现方法可以见django form (一)。

如果从数据库提取数据,内容为免会经常发生增删改的情况,如果在使用1的实现方法就很不现实,此时我们就需要一种可以实现动态select的方法了。

 先来看一段代码,不理解也没关系:

form中的类

 1 # coding:utf-8
 2 from django import forms
 3 from app01 import models
 4 
 5 
 6 class ImportForm(forms.Form):
 7     Host_List = (
 8         (1, '物理机'),
 9         (2, '虚拟机')
10     )
11     host_type = forms.IntegerField(widget=forms.Select(choices=Host_List))
12     hostname = forms.CharField()
13 
14     admin = forms.IntegerField(widget=forms.Select())
15 
16     def __init__(self, *args, **kwargs):
17         super(ImportForm, self).__init__(*args, **kwargs)
18 
19         self.fields['admin'].widget.choices = models.Simp.objects.all().values_list('id', 'username')

 上一段代码其实就已经实现了form中动态的select功能,下面展开的select就是从数据库中提取的数据:

 

实现的原理

我们要知道一个前提,django  form中要实现select,所传得参数必须是一个元组类型的数据。

如果你想知道为什么,其中是怎么实现的,为什么使用1的实现方法就是不行,那就耐心的往下看原理!这一段不属于django的知识点,属于python面向对象的内容。

我们知道python的类中可以定义静态字段,静态字段在类中加载后,被放入到内存中,如果再次修改静态字段,内存中的数据就不会在改变为什么呢?

因为静态字段是属于类的。
类中的静态字段会被加载放入到内存中,属于类里面的内容,在第一次运行程序的时候,
只加载了一次。而我们每一次创建类的对象时,默认会执行类下面的 __init__构造函数。
而静态字段属于类,不属于对象,所以之后的每一次访问时都不会再次加载类中的内容。
所以当我们修改文件中或者数据库中与静态字段有关联的数据内容后,
再次访问的时候,并不会修改内存中的数据。(除非我们把程序重启)

 

如何做?

通过类的继承关系我们知道,如果执行的方法在当前类下没有,就会自动去父类中查找,如果有就会执行。

我们可以在定义的form类下重定义__init__方法。

1     def __init__(self, *args, **kwargs):
2         super(ImportForm, self).__init__(*args, **kwargs)
3 
4         self.fields['admin'].widget.choices = models.Simp.objects.all().values_list('id', 'username')

 

 

第一句中的super:执行父类中的__init__方法

第二句这行代码什么意思呢,可以往父类中查找源码到底做了什么

查找父类中的__init__方法,可以看到self.fields = copy.deepcopy(self.base_fields)

这一句就是把form类下面的静态字段都深copy了一份放在了对象里。这样,我们只需要修改对象里面那份数据就可以了。而类下面的数据不需要改变。

self.fields的结果是一个字典,用['admin']就可以查找到在form类中定义的静态字段:admin = forms.IntegerField(widget=forms.Select(choices=Host_List))

通过.widget.choices的方法就可以修改静态字段中的参数了。

当前台页面再次访问时,就会拿到一份新的数据,生成了一个新元组,重新传到前端的html页面中。这样就实现了动态的select。

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/chenchao1990/p/5306479.html