Using a lazy value in a queryset filter?

128 views
Skip to first unread message

Sylvain

unread,
Jun 12, 2022, 2:59:43 PM6/12/22
to Django users
Hello,

I’m trying to use the current language of the user in a queryset, but the value gets resolved outside of the request-response cycle. I thought this could work since querysets are lazy, but I guess that doesn’t make the values they use lazy. Here’s an example of what I’m talking about:

from django.utils.translation import get_language

class MyManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(language=get_language())

class MyModel(models.Model):
    ...
    objects = MyManager()

Using this in a code path that’s in the request-response cycle works (eg. in a view), but using it in a form definition doesn’t (I get the default language instead of the one from the request):

class MyForm(forms.Form):
    option = forms.ModelChoiceField(queryset=MyModel.objects.all())

Is there a way to get this working without having to move the queryset call to the form __init__? Using django.utils.functional.lazy doesn’t work either because the value needs to be resolved in the filter.

Thanks!
Sylvain

Ryan Nowakowski

unread,
Jun 12, 2022, 5:14:41 PM6/12/22
to Django users
On Sun, Jun 12, 2022 at 11:46:44AM -0700, Sylvain wrote:
> Hello,
>
> I’m trying to use the current language of the user in a queryset, but the
> value gets resolved outside of the request-response cycle. I thought this
> could work since querysets are lazy, but I guess that doesn’t make the
> values they use lazy. Here’s an example of what I’m talking about:
>
> from django.utils.translation import get_language
>
> class MyManager(models.Manager):
> def get_queryset(self):
> return super().get_queryset().filter(language=get_language())
>
> class MyModel(models.Model):
> ...
> objects = MyManager()
>
> Using this in a code path that’s in the request-response cycle works (eg.
> in a view), but using it in a form definition doesn’t (I get the default
> language instead of the one from the request):
>
> class MyForm(forms.Form):
> option = forms.ModelChoiceField(queryset=MyModel.objects.all())

Can you post how you're using the form? Are you using the form in a
view? Can you post the view code?

Sylvain

unread,
Jun 17, 2022, 8:35:28 AM6/17/22
to Django users
The form is used in a view, yes, like so:

def objects_list(request):
    if request.method == "POST" and "delete" in request.POST:
        delete_form = MyForm(data=request.POST)

        if delete_form.is_valid():
            if delete_form.cleaned_data["confirm"]:
                delete_form.save()
                return redirect(...)
            else:
                return render(request, "delete_confirm.html", {"form": delete_form})
    ...
Reply all
Reply to author
Forward
0 new messages