Как предварительно заполнить поле выбора (Multiple)ChoiceField в Django на основе предыдущего выбора пользователя

Мне удалось сохранить и обновить выбор категорий, сделанный пользователем, в базе данных. Теперь я хочу предварительно заполнить MultipleChoiceSelect этим выбором, когда пользователь снова запросит форму, чтобы обновить свой выбор.

Итак, моя текущая форма всегда возвращает все доступные категории. Как я могу применить личный выбор пользователя к этому, чтобы его последний выбор был предварительно выбран в DOM?

# Models

class UserCategoryFilter(models.Model):
    """
    Saves the selected category filter by a user
    """
    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    categories_selected = models.CharField(max_length=2000)


class Category(models.Model):
    """
    Model to store all available categories
    """
    poller_category = models.CharField(max_length=30)
# Form

class SelectCategoryForm(forms.Form):
    choices = forms.ModelMultipleChoiceField(queryset=Category.objects.all(),
                                             widget=forms.CheckboxSelectMultiple)
# View

..
selection = filter_form.clean()
..

Вот как в настоящее время сохраняется выбор пользователя:

enter image description here

Вы можете установить начальное значение поля выбора при создании формы:

filter_form = SelectCategoryForm(
    request.POST, 
    initial={'choices': Category.objects.filter(<get_user's_category_here>)}
)

Вы не поделились моделями, поэтому построить запрос немного сложно, но просто измените фильтр, чтобы получить текущие категории пользователя.

В настоящее время выбор пользователя сохраняется в categories_selected:

{'choices': <QuerySet [<Category: Sports>, <Category: Lifestyle>]>}

Это не дружественная структура данных. Вместо этого, давайте сделаем ["Sports", "Lifestyle"].

# Get the cleaned data
selection = filter_form.clean()
selection = json.dumps([c.poller_category for c in selection['choices']])  # Add this

Теперь мы можем json.loads выделить и .filter(poller_category__in=selection).

Затем, мы передаем начальные варианты в SelectCategoryForm(initial={'choices': choices}).

@require_GET
def select_category(request):
    choices = ()
    user_category_filter_queryset = UserCategoryFilter.objects.filter(user=request.user)
    selection = user_category_filter_queryset.values_list('categories_selected', flat=True).first()
    if selection:
        try:
            selection = json.loads(selection)
        except JSONDecodeError:
            pass
        if selection:
            choices = Category.objects.filter(poller_category__in=selection)
    form = SelectCategoryForm(initial={
        'choices': choices,
    })
    return render(request, 'select-category.html', {'form': form})
Вернуться на верх