2011-12-20 73 views
2

我在我的應用程序中有兩種類型的用戶:auth.User,它來自django.contrib.auth(標準Django認證模塊)和mysql.User,它位於我自己的模塊中。另外,mysql.User繼承自一個抽象模型。整體看起來與此類似(某些領域進行了簡明扼要省略):Django:ManyToManyField創建重複列名

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`) 
); 

請注意,數據庫的中間表是如何在沒有命名衝突的情況下創建的,但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創建的命名衝突嗎?

+0

我想你不想在用戶和數據庫上分別定義所有者M2M關係,併爲用戶 - 用戶關係指定通過表;因此失去了抽象的優點(儘管也許你可以在資源上定義一個「所有者」屬性)。其他(瘋狂的)想法:將「通過」設置爲「%(類)所有者」並定義兩種M2M模型:UserOwner和DatabaseOwner。我真的不認爲它有效,但... – Arthur 2011-12-21 01:29:39

回答

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 
+0

這是我第一次嘗試,但你不能有一個ForeignKey關係抽象模型。換句話說,在這個提出的方法中資源不可能是抽象的。 – 2012-01-04 21:13:05