Sending data to a form using data from previous GET request

I have a dictionary app where users can view the words (Lemma) filtered by their first letter. I would like for users to be able to then filter those results according to combinations of part of speech (each Lemma has exactly one part of speech) or tags (each Lemma can have 0 to many tags); e.g., select only Lemma that are nouns or verbs or are tagged as agricultural vocabulary.

I currently have two forms, one for selecting the first letter and one for selecting the part of speech/tag (the facets).

class LemmaInitialLetterForm(forms.Form):
    LETTERS = [
        ...
    ] 
    initial = forms.ChoiceField(
        widget=forms.RadioSelect(
            attrs={"class": "lem_init"}
        ),
        choices=LETTERS
    )
class FacetSideBarForm(forms.Form):
    poss = forms.MultipleChoiceField(
        required=False,
        widget=forms.CheckboxSelectMultiple,
        label='Parts of speech', 
        choices=list()
    )
    tags = forms.MultipleChoiceField(
        required=False,
        widget=forms.CheckboxSelectMultiple,
        label='Tags', 
        choices=list()
    )

    def __init__(self, poss=None, tag_list=None, *args, **kwargs):
        super(FacetSideBarForm, self).__init__(*args, **kwargs)
        if poss:
            self.fields['poss'].choices = [
                (pos, pos)
                for pos in poss
            ]
        if tag_list:
            self.fields['tags'].choices = [
                (tag, tag)
                for tag in tag_list
            ]

I've been able to display a list of Lemma filtered by first letter with the following view:

class LemmaListView(generic.FormView):
    template_name = "emedict/lemma_home.html"
    lemmalist = None

    def get(self, request, *args, **kwargs):
        form = LemmaInitialLetterForm(self.request.GET or None)

        if form.is_valid():
            initial = request.GET["initial"]
            self.lemmalist = Lemma.objects.filter(
                Q(cf__startswith=initial.lower()) | Q(cf__startswith=initial.upper()),
                pos__type="COM"
            ).order_by("sortform")

        else:
            self.lemmalist = Lemma.objects.filter(
                Q(cf__startswith="a") | Q(cf__startswith="A"), 
                pos__type="COM"
            ).order_by("sortform")

        return self.render_to_response(self.get_context_data(form=form))
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["lem_search_form"] = LemmaAdvancedSearchForm
        context["lem_init_form"] = LemmaInitialLetterForm
        context["sidebar_form"] = FacetSideBarForm
        context["lemmalist"] = self.lemmalist

        if self.lemmalist:
            context["sidebar_form"] = FacetSideBarForm(
                Pos.objects.filter(id__in=self.lemmalist.values("pos")),
                Tag.objects.filter(id__in=self.lemmalist.values("tags"))               
            )

        return context

What I want is to be able to then use FacetSideBarForm to filter these results, using the current letter that's filtering the whole list of Lemma and keeping the same path, e.g., going from .../lemma?initial=A to .../lemma?initial=A&poss=verb&poss=noun&tags=speaking. All I've been able to do so far is have FacetSideBarForm lead to a different view that filters all Lemma according to part of speech and tag, but sends the user to a new path and loses the initial letter filter.

I haven't been able to figure out how to approach this problem, so I can't make my question more specific than "does anyone know how to do this?"

Вернуться на верх