Home > OS >  Using filter__in via Foreignkey relationship returns an empty queryset
Using filter__in via Foreignkey relationship returns an empty queryset

Time:10-06

I'm trying to use the queryset category_filter as a filter__in // Django doc for another query qs_poller. However, the query returns an empty set.

# View

def render_random_poller(request):

    if request.user.is_authenticated:

        category_filter = Category.objects.filter(usercategoryfilter__user=request.user)
        # Returns <QuerySet [<Category: Sports>, <Category: Lifestyle>, <Category: Environment>]>

        qs_poller = Poller.objects.filter(poller_category__category__in=category_filter).order_by('-created_on')[:100]
        # Returns an empty set, although the database holds 5 entries matching the category_filter

    else:
        # Get queryset without filter
        qs_poller = Poller.objects.filter().order_by('-created_on')[:100]

    # Query last 100 published Pollers
    items = list(qs_poller)

    # Pick a random Poller
    shuffled_poller = random.sample(items, 1)
    random_poller_id = shuffled_poller[0].poller_pk

    target_url = '/poller/'   str(random_poller_id)   '/'

    return redirect(target_url, request, random_poller_id)

# Models

class UserCategoryFilter(models.Model):

    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    categories_selected = models.ManyToManyField(Category)


class Poller(models.Model):

    created_by = models.ForeignKey(Account, on_delete=models.SET(get_deleted_user))
    poller_category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True)


class Category(models.Model):

    category = models.CharField(max_length=30)

CodePudding user response:

You are filtering incorrectly in qs_poller. By adding an extra __category you are actually filtering on the CharField itself, and not the foreign key that you want to filter on.

You want to instead do this:

qs_poller = Poller.objects.filter(poller_category__in=category_filter).order_by('-created_on')[:100]

CodePudding user response:

YOu should filter on the category, not the category field of the category, so:

qs_poller = Poller.objects.filter(
    poller_category__in=category_filter
).order_by('-created_on')[:100]

You can also simplify the filtering to:

qs_poller = Poller.objects.filter(
    poller_category__usercategoryfilter__user=request.user
).order_by('-created_on')[:100]

This will thus construct a query to find all Pollers with as poller_category a related category specified in the UserCategoryFilter model that is linked to request.user.

  • Related