Django Набор запросов m2m ForeignKey

#django #django-queryset

#django #django-набор запросов

Вопрос:

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

От:

 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 с идентификатором источника:

 {'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)
  

Комментарии:

1. Здесь Term также следует включить модели Source и

2. добавлены другие модели

Ответ №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 , пожалуйста, обратитесь к официальному документу об отношениях «многие к одному».