0

我有 2 张桌子说 TableA 和 TableB

   class A(models.Model)
      A_name = models.CharField(max_length=48,primary_key=True)
      A_version = models.DecimalField(max_digits=3, decimal_places=0,null=False,blank=False)
      A_type = models.CharField(max_length=32, blank=True)
      class Meta:
             unique_together = ("A_name", "A_version") 

   class B(models.Model)
     B_number = models.CharField(max_length=32 ,primary_key=True)
     A_name = models.ForeignKey(A,related_name="AA_name",on_delete=models.DO_NOTHING)
     A_version = models.ForeignKey(A,related_name="AA_version",on_delete=models.DO_NOTHING)
         class Meta:
             unique_together = ("B_number","A_name", "A_version") 

现在我想做这样的事情:从 A、B 中选择 *,其中 B.B_name=A.A_name 和 B.B_version=A.A_version 和 A.A_type="type_name"。我无法执行获取,因为 A_type 不是唯一的,它可以返回多个对象。请帮忙

4

2 回答 2

0

不确定这是否回答了您的问题,但如果您想通过使用连接仅通过一个查询获取所有对象,您可以使用select_related

all_b = B.objects.all().select_related('A_name', 'A_version')
some_b = all_b[0]
some_b.A_name # does not incur extra db query

如果您想要更多地控制查询,您可以随时添加过滤器:

B.objects.filter(A_name__A_type='type_name').select_related('A_name', 'A_version')
于 2012-10-18T03:44:08.230 回答
0

我认为模型的设计不是很好。A 模型的 A_name 和 A_version 是唯一的。这意味着总会有一个对象具有唯一的 A_name 和 A_version 组合。

在模型 B 中,您可以引用 ID 字段,因为这将为您提供唯一的 A_name 和 A_version 组合。

您需要在 B:s save 方法中做的是确保没有新的或现有的记录获得与数据库中已经存在的相同的 B_number 和 A 引用

 class B(models.Model)
     B_number = models.CharField(max_length=32, unique=True) #Don't use as primary key
     A        = models.ForeignKey(A,on_delete=models.DO_NOTHING)

    def save(self, *args, **kvargs):
        if self.id:
            try:
                b_s = B.objects.get(B_number=self.B_number, A=self.A).exclude(pk=self.id)

                #The existing combination already exists:
                raise ValueError('The combination of B_number and A already exists')

            except B.DoesNotExist:
                #No existing records violates the rule
                pass
        else:
            try:
                b_s = B.objects.get(B_number=self.B_number, A=self.A)

                #The existing combination already exists:
                raise ValueError('The combination of B_number and A already exists')

            except B.DoesNotExist:
                #No existing records violates the rule
                pass

         #All is good, no violation
         super(B, self).save(*args, **kvargs)

一旦这到位,您肯定知道当您在 A_type 上运行查询时,底层 B:s 是唯一的

示例数据:

ID        A_name        A_version    A_type
 1        "name1"       1.0          "type1"
 2        "name2"       1.1          "type1"
 3        "name2"       1.2          "type2"

 Model B
 ID  B_number  A
 1    "10"     1
 2    "20"     1
 3    "30"     2
 4    "40"     3

#Will return A.id=1 and A.id=2
a_s = A.objects.filter(A_type="type1")

for a in a_s:
    for b in a.b.all():
        print b.number, a.A_number, a.A_version

因为我没有时间自己测试,所以我对错别字进行了预订。

于 2012-10-18T09:31:43.737 回答