Django - Appengine中多表继承的替代方案

时间:2011-06-21 20:26:29

标签: django google-app-engine inheritance multi-table

我正在Google Appengine上开发一个Django应用程序,我遇到了一个数据库设计问题,其中多表继承似乎是最好的解决方案。但遗憾的是,Appengine不支持多表继承,因为它需要JOIN。我正在寻找满足以下要求的替代解决方案:

**见底部的更新**

有3种不同的用户类型或配置文件:

  1. 商业(即所有者)
  2. 员工
  3. 客户端
  4. 这些配置文件共享某些属性,但也具有各自类型的唯一属性。例如,所有配置文件都有联系电子邮件和电话号码,但只有企业需要提供徽标或指定其业务类型。

    此外,我需要能够从db(无论类型)检索Profile对象,并获取每个(Business,Employee或Client)的扩展或子配置文件。此外,Business,Employee或Client对象还应该能够轻松访问父配置文件。换句话说,关系需要双向工作(如profile.employeeemployee.profile)。

    到目前为止,我已经提出了两种可能的解决方案:

    子模型中的OneToOneField:

    class Profile(models.Model):
      # Profile may exist before user claims it
      user = models.OneToOneField(User, blank=True, null=True)  
      email ...
      phone ...
      ... other common fields ...
    
    class Business(models.Model):
      profile = models.OneToOneField(Profile, verbose_name="user profile", related_name="biz_profile")
    
    class Employee(models.Model):
      profile = models.OneToOneField(Profile, verbose_name="user profile", related_name="employee_profile")
    
    class Client(models.Model):
      profile = models.OneToOneField(Profile, verbose_name="user profile", related_name="client_profile")
    

    这样我就可以执行以下操作:profile.biz_profilebiz.profile

    父模型中的唯一通用外键:

    class Profile(models.Model):
        content_type=models.ForeignKey(ContentType)
        object_id=models.PositiveIntegerField()
        content_object=generic.GenericForeignKey('content_type','object_id')
        email ...
        phone ...
        ... other common fields ...
    
      class Meta:
          unique_together = ('content_type', 'object_id')
    
    class Business(models.Model):
        profiles = generic.GenericRelation(Profile)
    
    class Employee(models.Model):
      profiles = generic.GenericRelation(Profile)
    
    class Client(models.Model):
      profiles = generic.GenericRelation(Profile)
    

    这样我就可以执行以下操作:profile.content_objectbiz.profiles.all()[0]

    第一种方法(OneToOneField)似乎是最直接的,但我需要想出一个更好的方法来知道要调用哪个孩子,可能是通过在Profile模型中设置content_type来创建一个方法,如:

    def get_instance(self):
      # Need to look at contenttype framework, but you get the idea
      if self.content_type == 'business':
        return self.biz_profile
      elif self.content_type == 'employee':
        return self.employee_profile
      elif self.content_type == 'client':
        return self.client_profile
      return None
    

    我没有选择其中任何一种解决方案,所以我欢迎任何其他解决方案或对我所拥有的改进。

    提前致谢!

    更新
    自我第一次发布以来,我的原始要求已经改变事实证明我只需要父母>子访问NOT child> parent。鉴于此,我将使用独特的通用外键方法。但是,我仍然在寻找原始问题的答案,所以如果你有解决方案,不要害羞。

0 个答案:

没有答案