简体   繁体   English

Django中的多对多关系

[英]Many-to-many relationships in Django

I'm currently doing a personal project to have a better understanding of how the Django REST framework works.我目前正在做一个个人项目,以更好地了解 Django REST 框架的工作原理。 Essentially, I'm trying to build a web application that allows users to share files, kind of a simplified version of Google Drive/Dropbox.本质上,我正在尝试构建一个允许用户共享文件的 web 应用程序,类似于 Google Drive/Dropbox 的简化版本。

However, I'm having some trouble with many to many relationships in my models.但是,我在处理模型中的多对多关系时遇到了一些麻烦。 Essentially, I want each user to have its own folders, in each folder they would have zero or more files.本质上,我希望每个用户都有自己的文件夹,在每个文件夹中他们会有零个或多个文件。 A user could then share (read only access or allow write/delete) an entire folder or only individual files.然后,用户可以共享(只读访问或允许写入/删除)整个文件夹或仅共享单个文件。

  • A user can have one (home folder) or more folders一个用户可以拥有一个(主文件夹)或多个文件夹
  • A folder can have zero (empty folder) or more files一个文件夹可以有零个(空文件夹)或多个文件
  • A folder can be read by one (owner) or more users, and the same goes for files一个文件夹可以被一个(所有者)或多个用户读取,文件也是如此
  • Many users can access (read only or write) depending on their permission level a folder/file许多用户可以根据他们的权限级别访问(只读或写入)文件夹/文件

I'm trying to model this relationships as follows:我正在尝试 model 这种关系如下:

from django.db import models
from django.contrib.auth.models import User


class Folder(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    users_can_edit = models.ManyToManyField(User)
    users_can_see = models.ManyToManyField(User)



class File(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField()
    folder = models.ForeignKey(Folder, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now=True, editable=False)
    users_can_edit = models.ManyToManyField(User)
    users_can_see = models.ManyToManyField(User)

However, I get this error that I wasn't able to fix when I try to run the server:但是,当我尝试运行服务器时出现无法修复的错误:

ERRORS:
api.File.users_can_edit: (fields.E304) Reverse accessor for 'api.File.users_can_edit' clashes with reverse accessor for 'api.File.users_can_see'.
        HINT: Add or change a related_name argument to the definition for 'api.File.users_can_edit' or 'api.File.users_can_see'.
api.File.users_can_see: (fields.E304) Reverse accessor for 'api.File.users_can_see' clashes with reverse accessor for 'api.File.users_can_edit'.
        HINT: Add or change a related_name argument to the definition for 'api.File.users_can_see' or 'api.File.users_can_edit'.
api.Folder.user: (fields.E304) Reverse accessor for 'api.Folder.user' clashes with reverse accessor for 'api.Folder.users_can_edit'.
        HINT: Add or change a related_name argument to the definition for 'api.Folder.user' or 'api.Folder.users_can_edit'.
api.Folder.user: (fields.E304) Reverse accessor for 'api.Folder.user' clashes with reverse accessor for 'api.Folder.users_can_see'.
        HINT: Add or change a related_name argument to the definition for 'api.Folder.user' or 'api.Folder.users_can_see'.
api.Folder.users_can_edit: (fields.E304) Reverse accessor for 'api.Folder.users_can_edit' clashes with reverse accessor for 'api.Folder.user'.
        HINT: Add or change a related_name argument to the definition for 'api.Folder.users_can_edit' or 'api.Folder.user'.
api.Folder.users_can_edit: (fields.E304) Reverse accessor for 'api.Folder.users_can_edit' clashes with reverse accessor for 'api.Folder.users_can_see'.
        HINT: Add or change a related_name argument to the definition for 'api.Folder.users_can_edit' or 'api.Folder.users_can_see'.
api.Folder.users_can_see: (fields.E304) Reverse accessor for 'api.Folder.users_can_see' clashes with reverse accessor for 'api.Folder.user'.
        HINT: Add or change a related_name argument to the definition for 'api.Folder.users_can_see' or 'api.Folder.user'.
api.Folder.users_can_see: (fields.E304) Reverse accessor for 'api.Folder.users_can_see' clashes with reverse accessor for 'api.Folder.users_can_edit'.
        HINT: Add or change a related_name argument to the definition for 'api.Folder.users_can_see' or 'api.Folder.users_can_edit'.

I'm still a beginner and only know the basic of SQL. This being said, is this an approach appropriate or is there any other way you would model these relationships?我仍然是初学者,只知道 SQL 的基础知识。话虽这么说,这是一种合适的方法还是有其他方法可以 model 这些关系?

You have two ManyToManyField s to the same model, so the related_name=… s [Django-doc] are the same, and will clash.您有两个指向相同 model 的ManyToManyField ,因此 related_name related_name=… s [Django-doc]相同,并且会发生冲突。 You should specify the related_name=… s, so:您应该指定related_name=… s,因此:

from django.db import models
from django.conf import settings

class Folder(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField()
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    users_can_edit = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='folders_that_can_be_edited'
    )
    users_can_see = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='folders_that_can_be_seen'
    )

class File(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField()
    folder = models.ForeignKey(Folder, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now=True, editable=False)
    users_can_edit = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='files_that_can_be_edited'
    )
    users_can_see = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='files_that_can_be_seen'
    )

But it might be better to define a single ManyToManyField with a through=… model [Django-doc] that then encodes the permissions of that user-file combination, this will require less tables, and makes filtering, etc. more effective.但最好定义一个带有through=… model [Django-doc]ManyToManyField ,然后对该用户文件组合的权限进行编码,这将需要更少的表,并使过滤等更有效。


Note : It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly.注意:通常使用settings.AUTH_USER_MODEL [Django-doc]来引用用户 model 比直接使用User模型[Django-doc]更好。 For more information you can see the referencing the User model section of the documentation .有关详细信息,您可以参阅文档中引用User model的部分

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

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