25

I'm building a news website. While I tried to get the list of relative news which have the same tags. The error said:

The QuerySet value for an exact lookup must be limited to one result using slicing.

I have two models News and Tag. Tag is a many-to-many foreign key of News.

# "models.py"

class Tag(models.Model):
    name = models.CharField(max_length=40)

class News(models.Model):
    tag = models.ManyToManyField(Tag, blank=True, verbose_name='tag')

View:

def newsDetailView(request, news_pk):
    news = get_object_or_404(News, id=news_pk)
    tags = news.tag.annotate(news_count=Count('news'))
    relative_news = News.objects.filter(tag=tags)

    return render(request, "news_detail.html", {
        'news': news,
        'tags': tags,
        'relative_news': relative_news
    })
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
William
  • 3,724
  • 9
  • 43
  • 76

7 Answers7

32

The following will work:

def newsDetailView(request, news_pk):
    news = get_object_or_404(News, id=news_pk)
    relative_news = News.objects.filter(tag__id__in=news.tag.all())
Lemayzeur
  • 8,297
  • 3
  • 23
  • 50
  • Hi I find a small issue about this solution, the relative news will include the major news itself.How can I get the news's relative news except itself?Thank you so much! – William May 20 '18 at 20:04
  • That's great, to exclude the news itself, just add `exclude()` at the end. `.....exclude(id=news_pk)` this excludes the news from `relative_news` with the ID passed as argument or `.....exclude(id=news.pk)` this excludes the news from `relative_news` with its id – Lemayzeur May 21 '18 at 00:54
  • Thank you so much for your reply!Because I only need 6 relative news so my code is like this relative_news = News.objects.filter(tag__id__in=news.tag.all())[:6] after I add exclude(id=news_pk) ,it says:Cannot filter a query once a slice has been taken. Could you give me further solution ? Thank you so much! – William May 21 '18 at 01:30
  • Now I'm using a way to solve this conflict, in my view I use: relative_news = News.objects.filter(tag__id__in=news.tag.all()).exclude(id=news_pk) and in the template I use slice filter : |slice:":6" it works.I'm wondering is any other way can solve the 'Cannot filter a query once a slice has been taken.' – William May 21 '18 at 01:40
  • You must use `exclude()` to the queryset before using `slice` [:6]: `News.objects.filter(tag__id__in=news.tag.all()).exclude(id=news_pk)[:6]` – Lemayzeur May 21 '18 at 08:13
  • Really appreciate it! – William May 23 '18 at 01:03
  • Hi friend ,could you help me solve this issue https://stackoverflow.com/questions/50993171/app-cant-be-installed-in-django-virtual-environment ? – William Jun 22 '18 at 17:45
  • Hi friend ,could you help me solve this issue https://stackoverflow.com/questions/51211942/how-to-deleted-a-django-project-under-virtualenv – William Jul 06 '18 at 13:52
  • Hi friend, could you help me solve this issue https://stackoverflow.com/questions/66460662/django-how-to-display-third-level-comments-in-a-nested-comment-system – William Mar 03 '21 at 17:19
13

Generally this error occurs when we use model queryset at the place of django models object. In the given question you have done the same. "Objects.filter" returns the model query set there can be single or multiple django model objects, but "objects.get" returns single django model object. Or we can use .last() and .first() with "objects.filter".

11

this error rises if you use queryset or list in your filter params. For example,

News.objects.filter(title = a)

and here if "a" inside a filter is a queryset or list, then this error raises.

Odiljon Djamalov
  • 761
  • 8
  • 11
  • 1
    Yes, agree with this answer. Just changed `field_name=queryset` to `field_name__in=queryset` & it worked for me. – hygull Oct 18 '21 at 10:06
4

The problem you are facing is that you first take a filter queryset (a collection of objects from your database) for example: Book.objects.filter(subject='fiction') ) and then you are trying to use that filter as a parameter (like subject = 'fiction' in the previous one ) to obtain another filter queryset.

Instead you have to use an object using 'get' instead of 'filter' that is the previous example would become

book = Book.objects.get(subject='fiction')

and then use that object as parameter for next filter.

example: Book_shelf = BookShelf.objects.filter(book = book)
Sangeeth Joseph
  • 152
  • 1
  • 8
1

I also experienced the same issue, try doing this, instead of:

relative_news = News.objects.filter(tag=tags)

to

relative_news = News.objects.filter(tag=tags).first()

Dharman
  • 30,962
  • 25
  • 85
  • 135
Jayant Nigam
  • 171
  • 1
  • 9
1

I got the same error below:

ValueError: The QuerySet value for an exact lookup must be limited to one result using slicing.

Because I assigned the queryset made by filter() to category as shown below:

                       # Here                   # Here                 
Product.objects.filter(category=Category.objects.filter(pk=1))

So, I put __in after category as shown below, then the error was solved:

                              # ↓ Here
Product.objects.filter(category__in=Category.objects.filter(pk=1))

Or, I assigned the object made by get() to category as shown below, then the error was solved:

                                                # Here                 
Product.objects.filter(category=Category.objects.get(pk=1))
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
0

YOU CAN DO LIKE THIS list_inst=[]

for i in list_Series:
    list_inst += Episodes.objects.filter(id_serie=i.id_serie)
    
list_Episodes=list_inst
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 07 '23 at 14:52