如何识别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")
原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/12932621.html