0

TableA と TableB という 2 つのテーブルがあります

   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") 

今、私はこのようなことをしたいと思っています: select * from A, B where B.B_name=A.A_name and B.B_version=A.A_version and A.A_type="type_name". A_type は一意ではなく、複数のオブジェクトを返す可能性があるため、get を実行できません。助けてください

4

2 に答える 2

0

モデルのデザインはあまり良くないと思います。A モデルには、A_name と A_version が一緒に固有のものとして含まれています。つまり、A_name と A_version の一意の構成を持つ 1 つのオブジェクトが常に存在することになります。

モデル B では、一意の組み合わせ A_name と A_version が得られるため、ID フィールドを参照できます。

B:s save メソッドで行う必要があるのは、新規または既存のレコードが、DB に既に存在するものと同じ 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 に答える
0

これがあなたの質問に答えるかどうかはわかりませんが、結合を使用して 1 つのクエリだけですべてのオブジェクトを取得する場合は、次を使用できます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 に答える