2011-12-20 7 views
2

私のアプリケーションには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を実行するために行くときしかし、私はエラーを取得:

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

:確かに

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

を、./manage.py sql mysqlは(再び、一部の列およびALTER TABLE文は簡潔にするため省略)エラーの原因を示してい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で作成された名前の競合を避ける方法はありますか?

+0

ユーザーとデータベースでオーナーのM2M関係を個別に定義しないで、ユーザーとユーザーの関係のスルーテーブルを指定する必要はありません。抽象化の利点が失われます(Resource上に「所有者」プロパティを定義することもできます)。他の(クレイジーな)アイデア:「%(クラス)所有者」に「スルー」を設定して、両方のM2Mモデル(UserOwnerとDatabaseOwner)を定義します。私は本当にそれが動作するとは思わないが... – Arthur

答えて

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

これは私の最初の試行の1つでしたが、抽象モデルとのForeignKey関係はできません。言い換えると、この提案された方法では、リソースは抽象的ではありません。 –

関連する問題