如何识别Form字段中一对多或者多对多字段
models.py
from django.db import models class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() def __str__(self): return self.name class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() def __str__(self): return self.name class Book(models.Model): nid = models.AutoField(primary_key=True,verbose_name=" 编号") #定义在Xadmin查看页面中显示中文名称“编号” title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) # 与Publish建立一对多的关系,外键字段建立在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to='Author',) def __str__(self): return self.title
admin.py
from django.forms import ModelForm from app01.models import * #为book表定制modelform class BookModelForm(ModelForm): class Meta: model = Book fields = "__all__" labels={ "title":"书籍名称", "price":"价格", "publishDate":"出版日期" } form = BookModelForm() # 实例化一个对象form # ModelForm会把model下的Foreignkey、ManyToMany转换为form下的ModelChoiceFiled、 # ModelMultipleChoiceFiled字段,并且ModelMultipleChoiceFiledid字段继承ModelChoiceFiled字段 ''' ChoiceFiled ModelChoiceFiled(ChoiceFiled) ---- select(单选) ModelMultipleMChoiceFiled (ModelChoiceFiled)----select(多选) class Book(model.Model): title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) publish=model.Foreignkey(to="Publish") authors=model.ManyToMany(to="Author") from django import forms class BookForm(forms.Form): title = forms.CharField( max_length=32) publishDate=forms.DateField() price=forms.DecimalField(max_digits=5,decimal_places=2) publish = forms.ModelChoiceFiled(to="Publish") authors = forms.ModelMultipleChoiceField(to="Author") '''
views.py
from django.shortcuts import render,HttpResponse # Create your views here. from .admin import form def test(request): for bfield in form: print(bfield,type(bfield)) #<input type="text" name="title" maxlength="32" required id="id_title" /> <class 'django.forms.boundfield.BoundField'> # <input type="text" name="publishDate" required id="id_publishDate" /> <class 'django.forms.boundfield.BoundField'> # <input type="number" name="price" step="0.01" required id="id_price" /> <class 'django.forms.boundfield.BoundField'> # <select name="publish" required id="id_publish"> # <option value="" selected>---------</option> # </select> <class 'django.forms.boundfield.BoundField'> # <select name="authors" required id="id_authors" multiple="multiple"> # </select> <class 'django.forms.boundfield.BoundField'> #发现全部都是下面这种类型 #<class 'django.forms.boundfield.BoundField'>
我们打开BoundField源码看一看
from django.forms.boundfield import BoundField
发现有一个self.field=field,于是我们试着下面的方式打印看看
from django.shortcuts import render,HttpResponse # Create your views here. from .admin import form def test(request): for bfield in form:print(bfield.field, type(bfield.field)) #<django.forms.fields.CharField object at 0x00000239D0EDE668>
<class 'django.forms.fields.CharField'> # <django.forms.fields.DateField object at 0x00000239D0EDE6D8>
<class 'django.forms.fields.DateField'> # <django.forms.fields.DecimalField object at 0x00000239D0EDE748>
<class 'django.forms.fields.DecimalField'> # <django.forms.models.ModelChoiceField object at 0x00000239D0EDE7B8>
<class 'django.forms.models.ModelChoiceField'> # <django.forms.models.ModelMultipleChoiceField object at 0x00000239D0EDE828>
<class 'django.forms.models.ModelMultipleChoiceField'>
这样我们可以看出来哪些字段是一对多或者多对多字段了,我们知道
ModelMultipleChoiceField继承了ModelChoiceField,
所以可以通过以下方式进行识别一对多或者多对多的form字段:
from django.shortcuts import render,HttpResponse # Create your views here. from .admin import form def test(request): for bfield in form: #通过以下方式我们可以把form字段中的一对多或者多对多字段添加一个属性is_pop = True #这样我们通过判断form的字段里有没有is_pop = True,进而就能识别form字段中的一对一或者多对多字段 from django.forms.models import ModelChoiceField if isinstance(bfield.field, ModelChoiceField): # 如果form字段是一对多或多对多类型 bfield.is_pop = True # 为form字段加属性,以便之后取出判断是否为一对多或多对多字段 return HttpResponse("OK")