Django - ManyToMany字段 - 建立正确的链接

时间:2018-04-03 12:30:04

标签: python django python-3.x django-models django-views

python3 manager.py inspectdb(mysql)之后看了几个帮助和tuto,我仍然有一些错误和不正确的结果。

models.py

class A(models.Model):
    ida = models.AutoField(db_column='idA', primary_key=True)   
    col1 = #an another column
    has_B = models.ManyToManyField(B, related_name='a', through="AHasB", through_fields=('a_ida', 'b_idb'))
    #I had add this line after a tuto in django book for the manytomayfield

class B(models.Model):
    idb = models.AutoField(db_column='idB', primary_key=True)
    col1 = #an another column

class AHasB(models.Model):
    a_ida = models.ForeignKey(A)
    b_idb = models.ForeignKey(B)
    col1 = #an another column

view.py

def myview(request):

   for element in b.filter(idb__in=a.values('has_B').distinct()):

      print(element)

在我的数据库中,

A : 
ida  | col1  
1    | ...   
2    | ... 
3    | ... 

B : 
idb  | col1  
1    | ...   

AHasB : 
a_ida  | b_idb  
1      | 1

但是当我将结果(ida -> idb)显示为经典(SELECT idb,ida FROM A, B, AHasB WHERE AHasB.a_ida=A.ida AND AHasB.b_idb=B.idb)时,我有这个......

1  ->  1
2  ->  1
3  ->  1

在正常情况下,我只有1 - > 1。

也许这个模型不适合我后面的真实数据库。

修改

view.py

def myview(request):

   a = A.objects.All()
   b = B.objects.All()

   for element_a in a.filter("somefilters"):

      in_has_b = set(AHasB.objects.values_list('b_idb', flat=True));
      print(b.filter(idb__in=in_has_b))

1 个答案:

答案 0 :(得分:0)

如果要选择每个A实例引用/拥有的所有B实例:

bs_for_each_a = {}

for a in A.objects.all():
   bs = AHasB.objects.filter(a_ida=a).values('b_idb')
   bs_for_each_a[a] = bs

如果您需要不同的B,可以尝试在.distinct()之后添加values('b_idb'),但我没有对其进行测试。删除重复项的另一种方法是使用values_list('b_idb', flat=True)并在set()中传递查询结果:

for a in A.objects.all():
   bs = AHasB.objects.filter(a_ida=a).values_list('b_idb', flat=True)
   bs_for_each_a[a] = set(bs)