繁体   English   中英

Django中两个模型之间的ManyToMany关系

[英]ManyToMany Relationship between two models in Django

我正在尝试建立一个网站,用户可以添加他们正在学习的课程。 我想知道我应该如何添加 ManyToMany 关系。 这样我们就可以根据课程代码或讲师或任何字段获取课程中的所有用户。 我们还可以获得用户注册的课程。目前,我的数据库结构是:

class Course(models.Model):
    course_code = models.CharField(max_length=20)
    course_university = models.CharField(max_length=100)
    course_instructor = models.CharField(max_length=100)
    course_year = models.IntegerField(('year'), validators=[MinValueValidator(1984), max_value_current_year])

    def __str__(self):
        return self.course_code

和我的用户 model:

class Profile(AbstractUser):
    bio = models.TextField()
    image = models.ImageField(default='defaults/user/default_u_i.png', 
    courses = models.ManyToManyField('home.Course',related_name='courses')

    def __str__(self):
        return self.username

我想知道 ManyToMany 关系应该在用户 model 还是课程 model 中? 还是会有所不同?

编辑:为了将课程添加到 object 现在我正在使用这个视图,但它似乎不起作用:

@login_required
def course_add(request):

    if request.method == "POST":
        form = CourseForm(request.POST or none)
        if form.is_valid():
            course = form.save()
            request.user.add(course)
    else:
        form = CourseForm
    context = {
        'form':form
    }
    return render(request,'home/courses/course_add.html', context)

对于关系数据库,定义ManyToManyField的 model 无关紧要。 Django 将创建一个额外的表,其中包含两个ForeignKey到由ManyToManyField链接的两个模型。

添加的相关管理器等都是Django逻辑。 在窗帘后面,它会查询中间的桌子。

但是,您需要修复related_name=…参数 [Django-doc] 在这种情况下, related_name指定从CourseProfile反向关系的名称。 因此,它应该类似于'profiles'

class Profile(AbstractUser):
    bio = models.TextField()
    image = models.ImageField(default='defaults/user/default_u_i.png', 
    courses = models.ManyToManyField('home.Course', related_name='profiles')

    def __str__(self):
        return self.username

因此,您可以获得参加Course object 的人员:

mycourse.profiles.all()

并且您可以访问注册Profilecourses

myprofile.courses.all()

有关详细信息,请参阅文档的多对多关系部分

您可以将课程添加到用户的课程中:

@login_required
def course_add(request):
    if request.method == 'POST':
        form = CourseForm(request.POST)
        if form.is_valid():
            course = form.save()
            request.user.courses.add(course)
    else:
        form = CourseForm()
    context = {
        'form': form
    }
    return render(request,'home/courses/course_add.html', context)

您不需要添加相关名称。 在您的情况下,默认值为“courses_set”。 以下是摘录自: https://docs.djangoproject.com/en/dev/topics/db/queries/#backwards-related-objects

遵循“反向”关系 如果 model 有外键,外键 model 的实例将有权访问一个管理器,该管理器返回第一个 model 的所有实例。默认情况下,此管理器名为 FOO_set,其中 FOO 是源 model 名称, 小写。 该管理器返回 QuerySets,可以按照上面“检索对象”部分中的描述对其进行过滤和操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM