我的应用程序中有两种类型的用户: 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 回答
如何分别创建多对多表,避免使用ManyToMany字段?您可以使用管理器或方法返回给定资源的用户列表,反之亦然 .