简体   繁体   English

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

[英]ManyToMany Relationship between two models in Django

I am trying to build a website that users can add the courses they are taking.我正在尝试建立一个网站,用户可以添加他们正在学习的课程。 I want to know how should I add the ManyToMany relationship.我想知道我应该如何添加 ManyToMany 关系。 Such that we can get all users in a course based on the course code or instructor or any field.这样我们就可以根据课程代码或讲师或任何字段获取课程中的所有用户。 And we can also get the courses user is enrolled in. Currently, my Database structure is:我们还可以获得用户注册的课程。目前,我的数据库结构是:

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

and my user model:和我的用户 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

I was wondering should ManyToMany relationship be in User model or the course model?我想知道 ManyToMany 关系应该在用户 model 还是课程 model 中? Or will it make any difference at all?还是会有所不同?

EDIT : For adding course to post object now I am using this view but it seems to not work:编辑:为了将课程添加到 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)

For a relational databases, the model where you define the ManyToManyField does not matter.对于关系数据库,定义ManyToManyField的 model 无关紧要。 Django will create an extra table with two ForeignKey s to the two models that are linked by the ManyToManyField . Django 将创建一个额外的表,其中包含两个ForeignKey到由ManyToManyField链接的两个模型。

The related managers that are added, etc. is all Django logic.添加的相关管理器等都是Django逻辑。 Behind the curtains, it will query the table in the middle.在窗帘后面,它会查询中间的桌子。

You however need to fix the related_name=… parameter [Django-doc] .但是,您需要修复related_name=…参数 [Django-doc] The related_name specifies the name of the relation in reverse so from Course to Profile in this case.在这种情况下, related_name指定从CourseProfile反向关系的名称。 It thus should be something like 'profiles' :因此,它应该类似于'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

You thus can obtain the people that particiate in a Course object with:因此,您可以获得参加Course object 的人员:

mycourse.profiles.all()

and you can access the courses in which a Profile is enrolled with:并且您可以访问注册Profilecourses

myprofile.courses.all()

For more information, see the Many-to-many relationships section of the documentation .有关详细信息,请参阅文档的多对多关系部分

You can add a course to the courses of a user with:您可以将课程添加到用户的课程中:

@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)

You don't need to add the related name.您不需要添加相关名称。 Default is "courses_set" in your case.在您的情况下,默认值为“courses_set”。 Here is excerpt from: https://docs.djangoproject.com/en/dev/topics/db/queries/#backwards-related-objects以下是摘录自: https://docs.djangoproject.com/en/dev/topics/db/queries/#backwards-related-objects

Following relationships “backward” If a model has a ForeignKey, instances of the foreign-key model will have access to a Manager that returns all instances of the first model. By default, this Manager is named FOO_set, where FOO is the source model name, lowercased.遵循“反向”关系 如果 model 有外键,外键 model 的实例将有权访问一个管理器,该管理器返回第一个 model 的所有实例。默认情况下,此管理器名为 FOO_set,其中 FOO 是源 model 名称, 小写。 This Manager returns QuerySets, which can be filtered and manipulated as described in the “Retrieving objects” section above.该管理器返回 QuerySets,可以按照上面“检索对象”部分中的描述对其进行过滤和操作。

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

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