#django #django-forms
Вопрос:
У меня есть форма, содержащая автофокус MultipleChoiceField
, где выбор создается динамично на основе данного пользователя
class UpdateForm(forms.Form):
def __init__(self,names,*args,**kwargs):
super(UpdateForm,self).__init__(*args,**kwargs)
self.fields["list_names"] = forms.MultipleChoiceField(choices = zip(names,names),widget=forms.CheckboxSelectMultiple,label="Pick some names")
add_new = forms.BooleanField(initial=True, label="Add new names?",required=False)
delete_missing = forms.BooleanField(label = "Delete names?",required=False)
и это прекрасно работает как GET-запрос, проблемы возникают вместе с post-запросом:
Мое мнение заключается в следующем:
def update(request):
user = request.user
list_names = MyModel.objects.filter(user=user).all().values_list("nick_name",flat=True).distinct()
form = UpdateWishlistForm(names =list_names)
if request.method == "POST":
post_form = UpdateForm(request.POST)
if post_form.is_valid():
list_names = post_form.cleaned_data["list_names"]
add_new = post_form.cleaned_data["add_new"]
delete_missing = post_form.cleaned_data["delete_missing"]
messages.success(request, "Success")
context = {
"form":form,
}
redirect("home")
else:
#invalid post_form
messages.error(request, "Error")
context = {
"form":form,
}
return render(request, "discounttracker/update.html")
else: #Get request
context = {
"form":form,
}
return render(request, "myapp/update.html",context=context)
Значение post_form = UpdateForm(request.POST)
не проверяется, и post_form.errors
оно пустое.
Однако он содержит данные (перед вызовом post_form.is_valid()
).
print(post_form)
# UpdateForm: <UpdateForm bound=False, valid=Unknown, fields=(add_new;delete_missing;list_names)>
print(request.POST.dict())
#<QueryDict: {'csrfmiddlewaretoken': ['...'], 'add_new': ['on'], 'list_names': ['test_name_1']}>
но я замечаю, что он не связан, следовательно, не имеет силы. Но я не могу понять, почему это не «привязка» при разборе request.POST
?
Ответ №1:
В запросе на публикацию вам также нужно указать имена, поэтому:
list_names = MyModel.objects.filter(user=user).values_list("nick_name",flat=True).distinct()
form = UpdateWishlistForm(names=list_names)
if request.method == 'POST':
post_form = UpdateForm(names=list_names, data=request.POST)
# …
# …
Но я бы посоветовал работать с ModelMultipleChoiceField
[Django-doc] и, таким образом, передавать набор запросов. Поскольку имена ников, по-видимому, могут содержать дубликаты, возможно, было бы лучше создать Nickname
модель и использовать ForeignKey
s для этой модели.
Комментарии:
1. Я тоже пробовал это, но это бросает
__init__() got multiple values for argument 'names'
2. @CutePoison: вы, вероятно, использовали
UpdateForm(request.POST, names=list_names)
. Посколькуnames
это первый параметр конструктора формы, это означает, чтоrequest.POST
он рассматривается как значениеnames
параметра, а также второго, и это приводит к ошибке, поскольку для одного и того же параметра существует два значения.3. Да, я только что понял, что, написав это так, как ты, сделал разницу — в чем разница между этими двумя?
4. @CutePoison: см. редактирование комментария. Возможно , это было тесто для работы
def __init__(*args, names=None, **kwargs)
, а затем для создания этогоUpdateForm(request.POST, names=list_names)
.5. @CutePoison В
UpdateForm(request.POST, names=list_names)
request.POST
является позиционным аргументом, и, поскольку в вашем определении сигнатура метода имеетnames
первое значение, это значение для этого и сразу после того, как у вас есть ключевое слово arg дляnames
.