我有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”。我无法执行get,因为A_type不是唯一的,它可以返回多个对象。 Plz帮助
答案 0 :(得分: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')
答案 1 :(得分:0)
我认为模型的设计不是很好。 A模型将A_name和A_version一起作为唯一。这意味着总会有一个对象具有A_name和A_version的唯一组合。
在模型B中,您可以引用ID字段,因为这将为您提供唯一的组合A_name和A_version。
你需要在B中做什么:保存方法是确保没有新记录或现有记录获得与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
因为我没有时间自己测试错误而预订错别字。