2016-10-13 4 views
0

Я пытаюсь получить список с уникальным «источником», и все пользователи добавили «термины» для него, например.Django + Queryset + m2m + ForeignKey

от:

user1 s1 [t3,t4,t5] 
user1 s2 [t1,t2] 
user2 s1 [t1,t2] 
user2 s2 [t3,t4,t5] 

к:

s1 t1,t2,t3,t4,t5 
s2 t1,t2,t3,t4,t5 

мои модели:

class User_Filter(models.Model): 
    user = models.ForeignKey(User) 
    source = models.ForeignKey(Source, null=True) 
    terms = models.ManyToManyField(Term) 

class Source(models.Model): 
    title = models.CharField('name', max_length=100, blank=True) 
    url = models.URLField('url', unique=True) 

class Term(models.Model): 
    title = models.CharField('title', max_length=100, unique=True) 

Я играл с этим кодом:

sources = User_Filter.objects.values('source').distinct() 

Эта линия выплевывает Dict с исходным ID:

{'source': 1} 
{'source': 2} 

И с этой точки я застрял. Любая помощь действительно ценится.

Гадкий решение:

list = [] 
for s in User_Filter.objects.values('source').distinct(): 
    objs = User_Filter.objects.all().filter(source=s['source']) 
    source = Source.objects.get(id=s['source']).url 
    source_dict = {} 
    terms = [] 
    for obj in objs: 
     for term in obj.terms.all(): 
      if term.title not in terms: terms.append(term.title) 
    source_dict['terms']=terms 
    source_dict['url']=source 
    to_scraper.append(source_dict) 
print (list) 
+0

Здесь также следует добавить модели «Term» и «Source» –

+0

Другие модели добавлены – Pran

ответ

1

Вы можете получить данные с этим:

data = [] 

for source in Source.objects.all(): 
    terms = [] 

    for user in source.user_filter_set.all(): 
     terms.extend(user.terms.all().values_list('title', flat=True)) 

    data.append({'url': source.url, 'terms': list(set(terms))}) 

Вы итерацию по каждому Source и получить связанные с ним User_Filter экземпляров. Оттуда вы получите terms для каждого user и добавьте их в условия текущего source.

Затем вы добавляете в список data, представляющий собой обрабатываемый source. list(set(terms)) избавляется от возможных дубликатов в terms.


Для объяснения user_filter_set, пожалуйста, см official doc об отношениях много-к-одному.

+0

Это прекрасно работает. Спасибо! – Pran