【问题标题】:How to add value to a many-to-many field in Django如何为 Django 中的多对多字段添加值
【发布时间】:2021-08-25 18:28:57
【问题描述】:

假设我有如下关系:

class Student(AbstractBaseUser):
    # It inherits AbstractBaseUser and has it's own manger
    # note: I did forget to add editable here
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    firstname
    lastname
    ...


class Teacher(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True)
    firstname
    lastname
    email
    ...


class Meeting(models.Model):
    id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False)
    student = models.ManyToManyField(Student)
    teacher = models.ManyToManyField(Teacher)

我应该如何为“学生”或“教师”字段添加/设置值。我尝试将相关模型中的对象分配给它们,但得到一个错误

禁止直接分配到多对多集合的前端。改用 student.set()。

我也试过这个:

m = Meeting()
s = Student.objects.first() #to get a random student
m.student.add(s)

然后我得到: ValueError:无法添加“”:实例在数据库“None”上,值在数据库“default”上

我也是这样做的:

m = Meeting.objects.create() #It does only have two mentioned fields.
m.student.add(s)

我明白了: django.db.utils.ProgrammingError:列“meeting_id”是 bigint 类型,但表达式是 uuid 类型 第 1 行:..._meeting" ("meeting_id", "student_id") 值 ('c7688df9-... ^ 提示:您需要重写或转换表达式。

【问题讨论】:

标签: python django


【解决方案1】:

您创建一个Meeting,然后用Teachers 和Students 填充它,所以:

s1 = Student.objects.create(firstname='Foo', last_name='Bar')
s2 = Student.objects.create(firstname='Qux', last_name='Qux')
t1 = Teacher.objects.create(
    firstname='Some',
    last_name='One',
    email='someone@something.com'
)

m = Meeting.objects.create()
m.student.add(s1, s2)
m.teacher.add(t1)

有关详细信息,请参阅Many-to-many relationships section of the documentation

根据您在问题中分享的例外情况,您创建了Meeting 模型之前您创建了UUIDField 类型的主键。我们可以通过以下方式解决此问题:

  1. 删除Meeting 模型;
  2. 运行makemigrations;
  3. 创建一个新的Meeting 模型;
  4. 再次运行makemigrations;和
  5. 运行migrate更新数据库。

【讨论】:

  • 其实我也试过这个。我有一个错误。让我在主题中添加错误。
  • @TheMir:如 cmets 中所指定,您需要先为Meeting创建一条数据库记录,因此m = Meeting()不是 足够了,你需要m.save(),或者干脆使用Meeting.objects.create()
  • 我这样做了。将错误添加到主题。我认为它有一个与数据库类型相关的错误。考虑到所有模型的 id 类型为 uuid4。
  • @TheMir:最好分享有关模型主键的详细信息。
  • 我的错。请稍等。
【解决方案2】:

先保存Student对象和Teacher对象

>> student_data = {'firstname': 'John', 'last_name', 'Doe', }
>> student1 = Student.objects.create(**student_data )
>>student_data = {'firstname': 'Test', 'last_name', 'Test', }
>> student2 = Student.objects.create(**student_data )

>> teacher_data  = {'firstname': 'TeacherJohn', 'last_name': 'TeacherDoe', 'email': 'john.doe@mail.com'}
>> teacher = Teacher.objects.create(**teacher_data )

然后使用其他字段(m2m 除外)创建一个会议对象。然后添加/设置 m2m 对象。

meeting = Meeting.objects.create(**the_model_fields_as_dict)
meeting.student.add(student1, student2)
meeting.teacher.add(teacher )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 2011-02-01
    相关资源
    最近更新 更多