Как предварительно заполнить поле выбора (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()
..
Вот как в настоящее время сохраняется выбор пользователя:
Вы можете установить начальное значение поля выбора при создании формы:
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})