首页 文章

Django:ManyToManyField创建重复的列名

提问于
浏览
2

我的应用程序中有两种类型的用户: auth.User ,它来自django.contrib.auth(标准Django身份验证模块)和 mysql.User ,它位于我自己的模块中 . 此外, mysql.User 继承自抽象模型 . 整个事情看起来与此类似(为简洁起见省略了一些字段):

class Resource(Model):
  class Meta:
    abstract = True
  owners = ManyToManyField('auth.User', related_name='%(class)s_owners')

class User(Resource):
  name = CharField(max_length=16)
  host = CharField(max_length=64)

class Database(Resource):
  name = CharField(max_length=64)

正如你所看到的,我想让它变成多个 auth.Users 给定的 mysql.User 和给定的 mysql.Database ,因此是ManyToManyFields . 但是,当我去运行 ./manage.py syncdb 时,我收到错误:

_mysql_exceptions.OperationalError: (1060, "Duplicate column name 'user_id'")

实际上, ./manage.py sql mysql 显示了错误的来源(为简洁起见,省略了一些列和ALTER TABLE语句):

CREATE TABLE `mysql_database` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `name` varchar(64) NOT NULL,
    UNIQUE (`server_id`, `name`)
);
CREATE TABLE `mysql_user` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `name` varchar(16) NOT NULL,
    `host` varchar(64) NOT NULL,
    UNIQUE (`server_id`, `name`, `host`)
);
CREATE TABLE `mysql_database_owners` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `database_id` integer NOT NULL,
    `user_id` integer NOT NULL,
    UNIQUE (`database_id`, `user_id`)
);
CREATE TABLE `mysql_user_owners` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `user_id` integer NOT NULL,
    `user_id` integer NOT NULL, -- <<<<< here is the conflict >>>>>
    UNIQUE (`user_id`, `user_id`)
);

请注意如何在没有命名冲突的情况下创建Database的中间表,但User的表存在冲突 . 我没有看到ManyToManyField提供了一种方法来在中间表中提供列名,但不幸的是我认为这就是我需要的 .

我尝试的另一种方法是显式创建中间表并使用ManyToManyField的 through 选项,如下所示:

class Resource(models.Model):
  class Meta:
    abstract = True
  owners = models.ManyToManyField('auth.User', related_name='%(class)s_owners', through='Owner')

class Owner(models.Model):
  user = models.ForeignKey('auth.User', related_name='Resource_owners')
  resource = models.ForeignKey(Resource)

但后来我得到了这个错误:

AssertionError: ForeignKey cannot define a relation with abstract class Resource

这对Django来说是可以预期的 .

因此,如果没有将 mysql.User 重命名为 mysql.DBUser ,是否有办法避免Django创建的命名冲突?

1 回答

  • 0

    如何分别创建多对多表,避免使用ManyToMany字段?您可以使用管理器或方法返回给定资源的用户列表,反之亦然 .

    class Resource(models.Model):
        ...
    
       class Meta:
          abstract = True
    
       def owners(self):
           return ResourceOwner.objects.filter(resource=self)
    
    
    class ResourceOwners(models.Model):
        resource = models.ForeignKey(Resource)
        owner = models.ForeignKey(User)
    
        class Meta:
          abstract = True
    

相关问题