django choicefield Select 一个有效的选择
django choicefield Select a valid choice
我正在尝试提交我的模型,其中包含 ajax 我其他模型的加载信息。对于我的模型形式的 ChoiceField,我得到了这个错误;
Select a valid choice. 69 is not one of the available choices.
request.POST 看起来不错。我得到了我所有的领域。由于我的 remind_object 字段已经是 CharField,我应该可以将 ['69'] 保存到那里,但我不明白为什么会出现此错误?
*** request.POST: <QueryDict: {'csrfmiddlewaretoken': ['dTtWIUKCOytmYVsbGf7StxMmd4ywPd0gzvvraAgrqiLuiUfLv3xo2TD1lv9Xpcxs'], 'topic': ['dsfdsfs'], 'remind_date': ['2022-02-22 13:45:59'], 'reminder_object_type': ['Client'], 'remind_object': ['69'], 'detail': ['<p>fdgfdgfd</p>\r\n'], 'submit_reminder_create_form': ['']}>
models.py
class Reminder(models.Model):
user_owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reminder_user') # user.reminder_user
topic = models.CharField(max_length=100, blank=True, null=True)
remind_date = models.DateTimeField(blank=True, null=True)
reminder_object_type = models.CharField(max_length=100, blank=True, null=True)
# Client
# Contact
# Action
remind_object = models.CharField(max_length=999, blank=True, null=True)
detail = RichTextField(max_length=999999,blank=True, null=True)
reminder_status = models.CharField(max_length=100, default="Active", blank=True, null=True)
slug = models.SlugField(max_length=200, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.topic)
def save(self, *args, **kwargs):
self.slug = slugify(str(self.topic) + "-" + str(self.user_owner) + "-" + str(get_random_code()))
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('reminder-detailview', kwargs={'slug': self.slug})
forms.py
class ReminderModelForm(forms.ModelForm):
class Meta:
model = models.Reminder
fields = ('reminder_object_type', 'topic', 'remind_date', 'remind_object', 'detail')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['reminder_object_type'] = forms.ChoiceField(required=True, label="", widget=forms.RadioSelect(attrs={'class': 'form-check form-control'}), choices=(
("Client", "Client"),
("Contact", "Contact"),
("Action", "Action")
))
self.fields['topic'] = forms.CharField(required=True, max_length=100, label="", widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Topic'}))
self.fields['remind_date'] = forms.DateTimeField(required=True, label="", validators=[validate_greater_than_now], widget=DateTimeWidget(
attrs={'class':'form-control'},
usel10n = True,
bootstrap_version=4
) )
self.fields['remind_object'] = forms.ChoiceField(required=False, label="", widget=forms.Select(attrs={'class': 'form-control'}))
self.fields['detail'] = forms.CharField(required=False, max_length=999999, widget=CKEditorWidget(attrs={'class' : 'form-control'}))
views.py
class ReminderListView(generic.ListView):
model = models.Reminder
template_name = 'crm/reminder_list.html'
ordering = ['-created']
def post(self, request, *args, **kwargs):
if 'submit_reminder_create_form' in self.request.POST:
print("*** request.POST: ", request.POST)
reminder_form = forms.ReminderModelForm(self.request.POST, self.request.FILES)
if reminder_form.is_valid():
print("*** request.POST: ", request.POST)
instance = reminder_form.save(commit=False)
instance.user_owner = self.request.user
instance.save()
reminder_form = forms.ReminderModelForm()
messages.success(self.request, f'{instance.topic} created successfully')
return redirect('reminder-detailview', slug=instance.slug)
else:
messages.warning(self.request, 'The form is not valid, please check the form fields properly!')
context = {
'reminder_create_form':forms.ReminderModelForm(self.request.POST, self.request.FILES),
'all_reminders': models.Reminder.objects.all().order_by('-created')
}
return render(request, 'crm/reminder_list.html', context, status=404)
def get_context_data(self, **kwargs):
context = super(ReminderListView, self).get_context_data(**kwargs)
context['all_reminders'] = models.Reminder.objects.all().order_by('-created')
context['sidebar_in'] = 'Reminder'
context['time_is'] = timezone.now()
context['reminder_create_form'] = forms.ReminderModelForm
context['active_reminders'] = models.Reminder.objects.filter(reminder_status = 'Active').filter(remind_date__lte = timezone.now() ).order_by('-created')
return context
html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
{{ reminder_create_form.media }}
<form id="reminder-create-form" method="POST" enctype="multipart/form-data" class="needs-validation"> {% csrf_token %}
{{reminder_create_form|crispy}}
</form>
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<!-- my custom -->
<script>
// bu js kısmı; sadece html formuna verilerin istediğimiz gibi bağlı-dropdown şeklinde yüklenmesini sağlıyor, ama forma kaydetmede forms.py da overwrite ettiğimiz init çalışacak
$(document.getElementById("reminder-create-form").elements["reminder_object_type"]).change(function () {
var selectedValue = $(this).val();
$.ajax({
url: "{% url 'ajax_reminder_type_view' %}",
data: { 'gonderilen_kelime': selectedValue, },
success: function (data) {
$(document.getElementById("reminder-create-form").elements["remind_object"]).html(data);
}
});
});
</script>
ajax_loading.html
{% for i in aranacak_objeler %}
<option value="{{ i.pk }}">
{% if i.name %}
{{ i.name }} {% if i.client_owner %} - Client: {{i.client_owner}} {% endif %}
{% else %}
{{ i.topic }} - Client: {{i.client_owner}} - Created: {{i.created|date:"F d, Y"}}
{% endif %}
</option>
{% endfor %}
错误发生在通过to_python或django.form.Fieldclass的验证方法进行表单验证的过程中。您正在做的是将无效值传递给您的字段。无效值可以是不在选择列表或元组中的值,但如果您确定该值在‖选择列表中,只需检查字段及其小部件。
用于字段验证的值严格取决于小部件指定的输入格式。如果您对字段的小部件使用 forms.RadioSelect,则小部件会将字符串值传递给字段,而 forms.CheckboxSelectMultiple 小部件会传递列出的值,例如 ['apple'、'orange'、.. .]。问题是每个字段都有自己可接受的验证数据类型。例如,MultipleChoiceField 只接受列表或元组,而 ChoiceField 只接受字符串。也许字段小部件中指定的值类型(用于验证的值类型)与字段期望的值类型之间可能存在冲突。也许您想在传递给 single-element 列表值(或相反)时为 CharField 保存一个字符串值?
您可以在此处检查特定字段可接受的数据类型。 https://github.com/django/django/blob/737542390af27616d93f86cd418e2d7f3e874b27/django/forms/fields.py
我正在尝试提交我的模型,其中包含 ajax 我其他模型的加载信息。对于我的模型形式的 ChoiceField,我得到了这个错误;
Select a valid choice. 69 is not one of the available choices.
request.POST 看起来不错。我得到了我所有的领域。由于我的 remind_object 字段已经是 CharField,我应该可以将 ['69'] 保存到那里,但我不明白为什么会出现此错误?
*** request.POST: <QueryDict: {'csrfmiddlewaretoken': ['dTtWIUKCOytmYVsbGf7StxMmd4ywPd0gzvvraAgrqiLuiUfLv3xo2TD1lv9Xpcxs'], 'topic': ['dsfdsfs'], 'remind_date': ['2022-02-22 13:45:59'], 'reminder_object_type': ['Client'], 'remind_object': ['69'], 'detail': ['<p>fdgfdgfd</p>\r\n'], 'submit_reminder_create_form': ['']}>
models.py
class Reminder(models.Model):
user_owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='reminder_user') # user.reminder_user
topic = models.CharField(max_length=100, blank=True, null=True)
remind_date = models.DateTimeField(blank=True, null=True)
reminder_object_type = models.CharField(max_length=100, blank=True, null=True)
# Client
# Contact
# Action
remind_object = models.CharField(max_length=999, blank=True, null=True)
detail = RichTextField(max_length=999999,blank=True, null=True)
reminder_status = models.CharField(max_length=100, default="Active", blank=True, null=True)
slug = models.SlugField(max_length=200, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.topic)
def save(self, *args, **kwargs):
self.slug = slugify(str(self.topic) + "-" + str(self.user_owner) + "-" + str(get_random_code()))
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('reminder-detailview', kwargs={'slug': self.slug})
forms.py
class ReminderModelForm(forms.ModelForm):
class Meta:
model = models.Reminder
fields = ('reminder_object_type', 'topic', 'remind_date', 'remind_object', 'detail')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['reminder_object_type'] = forms.ChoiceField(required=True, label="", widget=forms.RadioSelect(attrs={'class': 'form-check form-control'}), choices=(
("Client", "Client"),
("Contact", "Contact"),
("Action", "Action")
))
self.fields['topic'] = forms.CharField(required=True, max_length=100, label="", widget=forms.TextInput(attrs={'class':'form-control', 'placeholder': 'Topic'}))
self.fields['remind_date'] = forms.DateTimeField(required=True, label="", validators=[validate_greater_than_now], widget=DateTimeWidget(
attrs={'class':'form-control'},
usel10n = True,
bootstrap_version=4
) )
self.fields['remind_object'] = forms.ChoiceField(required=False, label="", widget=forms.Select(attrs={'class': 'form-control'}))
self.fields['detail'] = forms.CharField(required=False, max_length=999999, widget=CKEditorWidget(attrs={'class' : 'form-control'}))
views.py
class ReminderListView(generic.ListView):
model = models.Reminder
template_name = 'crm/reminder_list.html'
ordering = ['-created']
def post(self, request, *args, **kwargs):
if 'submit_reminder_create_form' in self.request.POST:
print("*** request.POST: ", request.POST)
reminder_form = forms.ReminderModelForm(self.request.POST, self.request.FILES)
if reminder_form.is_valid():
print("*** request.POST: ", request.POST)
instance = reminder_form.save(commit=False)
instance.user_owner = self.request.user
instance.save()
reminder_form = forms.ReminderModelForm()
messages.success(self.request, f'{instance.topic} created successfully')
return redirect('reminder-detailview', slug=instance.slug)
else:
messages.warning(self.request, 'The form is not valid, please check the form fields properly!')
context = {
'reminder_create_form':forms.ReminderModelForm(self.request.POST, self.request.FILES),
'all_reminders': models.Reminder.objects.all().order_by('-created')
}
return render(request, 'crm/reminder_list.html', context, status=404)
def get_context_data(self, **kwargs):
context = super(ReminderListView, self).get_context_data(**kwargs)
context['all_reminders'] = models.Reminder.objects.all().order_by('-created')
context['sidebar_in'] = 'Reminder'
context['time_is'] = timezone.now()
context['reminder_create_form'] = forms.ReminderModelForm
context['active_reminders'] = models.Reminder.objects.filter(reminder_status = 'Active').filter(remind_date__lte = timezone.now() ).order_by('-created')
return context
html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
{{ reminder_create_form.media }}
<form id="reminder-create-form" method="POST" enctype="multipart/form-data" class="needs-validation"> {% csrf_token %}
{{reminder_create_form|crispy}}
</form>
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<!-- my custom -->
<script>
// bu js kısmı; sadece html formuna verilerin istediğimiz gibi bağlı-dropdown şeklinde yüklenmesini sağlıyor, ama forma kaydetmede forms.py da overwrite ettiğimiz init çalışacak
$(document.getElementById("reminder-create-form").elements["reminder_object_type"]).change(function () {
var selectedValue = $(this).val();
$.ajax({
url: "{% url 'ajax_reminder_type_view' %}",
data: { 'gonderilen_kelime': selectedValue, },
success: function (data) {
$(document.getElementById("reminder-create-form").elements["remind_object"]).html(data);
}
});
});
</script>
ajax_loading.html
{% for i in aranacak_objeler %}
<option value="{{ i.pk }}">
{% if i.name %}
{{ i.name }} {% if i.client_owner %} - Client: {{i.client_owner}} {% endif %}
{% else %}
{{ i.topic }} - Client: {{i.client_owner}} - Created: {{i.created|date:"F d, Y"}}
{% endif %}
</option>
{% endfor %}
错误发生在通过to_python或django.form.Fieldclass的验证方法进行表单验证的过程中。您正在做的是将无效值传递给您的字段。无效值可以是不在选择列表或元组中的值,但如果您确定该值在‖选择列表中,只需检查字段及其小部件。
用于字段验证的值严格取决于小部件指定的输入格式。如果您对字段的小部件使用 forms.RadioSelect,则小部件会将字符串值传递给字段,而 forms.CheckboxSelectMultiple 小部件会传递列出的值,例如 ['apple'、'orange'、.. .]。问题是每个字段都有自己可接受的验证数据类型。例如,MultipleChoiceField 只接受列表或元组,而 ChoiceField 只接受字符串。也许字段小部件中指定的值类型(用于验证的值类型)与字段期望的值类型之间可能存在冲突。也许您想在传递给 single-element 列表值(或相反)时为 CharField 保存一个字符串值?
您可以在此处检查特定字段可接受的数据类型。 https://github.com/django/django/blob/737542390af27616d93f86cd418e2d7f3e874b27/django/forms/fields.py