相当于Rail的Django已经通过了

时间:2015-01-30 00:07:06

标签: ruby-on-rails django relationships has-one

Django中是否有等同于has_one :through的内容?

我有UserCompanyCompanyMember型号。 CompanyMember具有UserCompany的外键。 User可以通过Company模型属于CompanyMember。假设User

CompanyMember是唯一的

在Rails中,这种关系看起来像

class User < ActiveRecord::Base
  has_one :company_member
  has_one :company, :through => :company_member
end

class Company < ActiveRecord::Base
  has_many :company_members
end

class CompanyMember < ActiveRecord::Base
  belongs_to :company
  belongs_to :user
end

我可以使用user.company来吸引用户的公司。

在Django中,我有这样的模型

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


class Company(models.Model):
    name = models.CharField()


class CompanyMember(models.Model):
    company = models.ForeignKey(Company)
    user = models.ForeignKey(User, unique=True)
    is_company_admin = models.BooleanField(default=False)

是否有可能让user.company像Rails一样工作?我也希望能够在查询集过滤器中使用它,例如user__company=company

1 个答案:

答案 0 :(得分:2)

这应该做你想要的:

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


class Company(models.Model):
    name = models.CharField()
    users = models.ManyToManyField(User, through='CompanyMember')

class CompanyMember(models.Model):
    company = models.ForeignKey(Company)
    user = models.ForeignKey(User, unique=True)

更多信息:https://docs.djangoproject.com/en/1.7/topics/db/models/#extra-fields-on-many-to-many-relationships

<强>更新

要访问给定用户的公司,您现在可以执行以下操作:

myuser.company_set.first()

您可能不想更改内置的用户模型。但是,您可以使用代理模型轻松添加自己的便捷方法/属性,例如:

class MyUser(User):
    @property
    def company(self):
        return self.company_set.first()
    class Meta:
        proxy=True

然后,每当您通常使用User对象时,请改用MyUser,它将为您提供便利属性。例如:

MyUser.objects.get(id=123)

的记录相同
User.objects.get(id=123)

但是您将在对象上拥有额外的便利方法/属性。例如:

myuser = MyUser.objects.get(id=123)
myuser.company