TypeError: Direct assignment to the forward side of a many-to-many set is prohibited.(解决办法)


首先是还原犯罪现场:

首先我定义了一个Teacher模型(testapp/models.py下)

class Teacher(models.Model):
    SUBJECT_CHOICE = (
        ('Math','数学'),
        ('Chinese','语文'),
        ('English','英语'),
        ('PE','体育'),
        ('Painting','美术'),
        ('Music','音乐'),
    )
    name = models.CharField(max_length=12)
    subject = models.CharField('主教课程',max_length=12,choices=SUBJECT_CHOICE,default='Math')

    def __str__(self):
        return self.name

一个学校模型:

class School(models.Model):
    name = models.CharField(max_length=12)
    teacher = models.ManyToManyField('Teacher')

    def __str__(self):
        return self.name

然后运行以下命令:

python manage.py makemigrations testapp
python manage.py migrate
python manage.py shell

然后进入Shell环境,创建Teacher的实例,这些都没有错误。

创建完后如下:

>>> from testapp.models import *
>>> Teacher.objects.all()
<QuerySet [<Teacher: 小哈>, <Teacher: 爱丽丝>, <Teacher: 李白>, <Teacher: 托尼>, <Teacher: 阿宝>, <Teacher: 歌姬>]>

当我创建School的实例时,运行如下语句:
School.objects.create(name='希望小学',teacher=Teacher.objects.all()[:4])

结果就出现了这个错误:

TypeError: Direct assignment to the forward side of a many-to-many set is prohibited.Use teacher.set() instead.


突然醒悟,多对多字段是不能用create的,需要用add来添加实例!


但是随之又有一个问题,想要用add,需要先获取School的某个实例才行,但是我的School就是个空的啊,怎么能创建实例呢?

这个我真的是百思不得其解,网上查解决方案也差不到,最后干脆用了这样一个歪门邪道:

class School(models.Model):
    name = models.CharField(max_length=12)
    teacher = models.ManyToManyField('Teacher',null=True)

    def __str__(self):
        return self.name

即先把多对多字段设为允许空值,或者设一个default也可以,然后就可以先创建School的实例,再通过实例添加teacher字段。
肯定不是正解,django刚入门这个确实是还没搞得太明白,以后如果遇到了更好的办法,再更新吧。


我真是太傻了,多对多关系和一对多关系很像的啊,居然忘了可以反向关联添加学校的实例。。。。

所以正解如下:

>>> t1 = Teacher.objects.create(name='托尼',subject='English')
>>> t2 = Teacher.objects.create(name='爱丽丝',subject='Painting')
>>> t3 = Teacher.objects.create(name='阿飞',subject='Math')
>>> t1.school_set.all()
<QuerySet []>
>>> t1.school_set.create(name='希望小学')
<School: 希望小学>
>>> School.objects.all()
<QuerySet [<School: 希望小学>]>
>>> sc = School.objects.get(pk=1)
>>> sc.teacher.add(t2,t3)
>>> sc.teacher.all()
<QuerySet [<Teacher: 托尼>, <Teacher: 爱丽丝>, <Teacher: 阿飞>]>

你可能感兴趣的:(Django)