如何根据以前的用户选择在 Django 中预填充(多个)ChoiceField
How to pre-populate (Multiple)ChoiceField in Django based on previous user selection
我设法将用户选择的类别存储并更新到数据库中。现在我想在用户再次查询表单时使用此选择预填充 MultipleChoiceSelect。
所以我当前的表单将始终 return 所有可用类别。我如何将用户的个人选择应用于此,以便在 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
@require_POST
def save_category_filter(request):
[..]
# Get the form instance
filter_form = SelectCategoryForm(request.POST)
# Form validation
if filter_form.is_valid():
# Get the cleaned data
selection = filter_form.clean()
# Check if user already has a filter instance
instance_exists = UserCategoryFilter.objects.filter(user=request.user)
# If not create, else update
if not instance_exists:
filter_instance = UserCategoryFilter(user=request.user,
categories_selected=selection)
filter_instance.save()
else:
# Update existing instance
UserCategoryFilter.objects.filter(user=request.user).update(categories_selected=selection)
pass
[..]
这就是用户选择当前保存在 categories_selected
中的方式:
{'choices': <QuerySet [<Category: Sports>, <Category: Lifestyle>]>}
您可以在创建表单时设置选项字段的初始值:
filter_form = SelectCategoryForm(
request.POST,
initial={'choices': Category.objects.filter(<get_user's_category_here>)}
)
您没有共享模型,因此构建查询有点棘手,但只需更改过滤器即可获取用户的当前类别。
This is how the selection of the user is currently saved in 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})
我设法将用户选择的类别存储并更新到数据库中。现在我想在用户再次查询表单时使用此选择预填充 MultipleChoiceSelect。
所以我当前的表单将始终 return 所有可用类别。我如何将用户的个人选择应用于此,以便在 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
@require_POST
def save_category_filter(request):
[..]
# Get the form instance
filter_form = SelectCategoryForm(request.POST)
# Form validation
if filter_form.is_valid():
# Get the cleaned data
selection = filter_form.clean()
# Check if user already has a filter instance
instance_exists = UserCategoryFilter.objects.filter(user=request.user)
# If not create, else update
if not instance_exists:
filter_instance = UserCategoryFilter(user=request.user,
categories_selected=selection)
filter_instance.save()
else:
# Update existing instance
UserCategoryFilter.objects.filter(user=request.user).update(categories_selected=selection)
pass
[..]
这就是用户选择当前保存在 categories_selected
中的方式:
{'choices': <QuerySet [<Category: Sports>, <Category: Lifestyle>]>}
您可以在创建表单时设置选项字段的初始值:
filter_form = SelectCategoryForm(
request.POST,
initial={'choices': Category.objects.filter(<get_user's_category_here>)}
)
您没有共享模型,因此构建查询有点棘手,但只需更改过滤器即可获取用户的当前类别。
This is how the selection of the user is currently saved in
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})