Dr_Elvis
@Dr_Elvis
В гугле забанен

Как объединить несколько QuerySet в один без повторений?

Имеется 4 модели:
class Country(models.Model):
    code = models.CharField(unique=True, max_length=2, help_text='Максимум 2 символа в верхнем регистре', verbose_name='Код IATA')
    name_en = models.CharField(max_length=150, help_text='Максимум 150 символов', verbose_name='Название страны на английском', blank=True, null=True)
    name_ru = models.CharField(max_length=150, help_text='Максимум 150 символов', verbose_name='Название страны на русском', blank=True, null=True)


class City(models.Model):
    code = models.CharField(unique=True, max_length=3, help_text='Максимум 3 символа в верхнем регистре', verbose_name='Код IATA', default='MOW')
    name_en = models.CharField(max_length=150, help_text='Максимум 150 символов', verbose_name='Название города на английском', blank=True, null=True)
    name_ru = models.CharField(max_length=150, help_text='Максимум 150 символов', verbose_name='Название города на русском', blank=True, null=True)
    coordinates_lat = models.FloatField(help_text='Координата широты города', verbose_name='Широта', blank=True, null=True)
    coordinates_lng = models.FloatField(help_text='Координата долготы города', verbose_name='Долгота', blank=True, null=True)
    country_code = models.ForeignKey(Country, max_length=2, help_text='Максимум 2 символа в верхнем регистре', verbose_name='Код страны', related_name='link_to_country', to_field='code', default='RU')


class Tag(models.Model):
    tag = models.CharField(max_length=250, help_text='Максимум 250 символов.', verbose_name='Тег')
    slug = models.SlugField(unique=True, verbose_name='Ссылка')

class Entry(models.Model):
    author = models.ForeignKey(User, verbose_name='Автор')
    title = models.CharField(max_length=255, help_text='Максимум 255 символов.', verbose_name='Название новости')
    slug = models.SlugField(unique=True, help_text='Только английские буквы и дефисы.', verbose_name='Ссылка')
    content = tinymce_models.HTMLField(help_text='Полный текст новости', verbose_name='Полный текст новости')
    tags = models.ManyToManyField(Tag, verbose_name='Теги')
    pub_date = models.DateTimeField(default=datetime.datetime.now, verbose_name='Дата публикации')
    to_city = models.ForeignKey(City, verbose_name='Город прилета', related_name='to_city')


Далее есть views.py в которой реализован фильтр по тегам, городу или стране:
def tag(request, slug, pagenumber=1):
    tag_tag = Entry.objects.filter(tags__slug=slug)
    tag_city = Entry.objects.filter(to_city__name_en=slug)
    tag_country = Entry.objects.filter(to_city__country_code__name_en=slug)
    tagnews = tag_tag | tag_city | tag_country
    currentpage = Paginator(tagnews, 10)
    context = {
        'title': 'Поиск по тегам',
        'tagnews': currentpage.page(pagenumber),
    }
    return HttpResponse(render_to_string('tag_news.htm', context))


то есть я делаю 3 выборки:
- по отдельно заведенному тегу
- по городу
- по стране
В строчке "tagnews = tag_tag | tag_city | tag_country" происходит не объединение всех результатов, а склейка.
Смысл в том, что в результате у меня происходит вывод одних и тех же новостей, а мне нужно сделать чтобы в результате было только уникальные новости, без повторов.
  • Вопрос задан
  • 5132 просмотра
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Django
Седой и строгий
Чтобы убрать повторения, можно преобразовать QuerySet в множество
tagnews = set(tag_tag | tag_city | tag_country)
Но лучше вместо трёх запросов сделать один
from django.db.models import Q
tagnews = Entry.objects.filter(Q(tags__slug=slug) | Q(to_city__name_en=slug) | Q(to_city__country_code__name_en=slug))
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы