E
E
Elvis2017-03-12 14:25:50
Django
Elvis, 2017-03-12 14:25:50

How to merge multiple QuerySet into one without repetition?

There are 4 models:

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

Next, there is views.py which implements a filter by tags, city or country:
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))

that is, I make 3 selections:
- by a separately entered tag
- by city
- by country
In the line "tagnews = tag_tag | tag_city | tag_country" all the results are not combined, but merged.
The point is that as a result I get the same news output, and I need to make sure that the result is only unique news, without repetitions.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Gornostaev, 2017-03-12
@Dr_Elvis

To remove repetitions, you can convert the QuerySet into a set
. But it’s better to make one instead of three queries.

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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question