将选项从视图传递到表单
Pass choices from views to form
我使用 Bannerform
形式通过 add_banner
视图(和模板)创建新的 Banner
对象。我使用 class Options
来确定在 Bannerform
(affiliation
字段)形式中允许哪些 affiliation
对象。
我正在尝试将选项从视图传递到表单,但它给了我 ValueError:要解压的值太多(预期为 2)
我的代码在 new_affiliation
是 ForeignKey 时有效,但现在我需要更多值。我想我必须在 views
中确定 'choices' 否则我会在第一次迁移时遇到问题(它似乎是从 models.py
而不是从 views.py
调用数据库表,所以如果我把 Options.objects.get(id=1)
放在 models.py
上,它会给出错误,因为表还不存在)。
我的form.py
:
from django import forms
from core.models import Options, Banner, Affiliation #somethings other
class BannerForm(forms.ModelForm):
name = forms.CharField(max_length=32)
affiliation = forms.ChoiceField('choices')
#affiliation = forms.ModelChoiceField('choices') #same error
class Meta:
model = Banner
exclude = (#some fields)
我的models.py
:
from django.db import models
from django.contrib.auth.models import User
from django import forms
class Options(models.Model):
new_affiliation = models.ManyToManyField('Affiliation')
#new_affiliation = models.ForeignKey('Affiliation') #this worked (with some changes in views)
class Affiliation(models.Model):
name = models.CharField(max_length=32, unique=True)
class Banner(models.Model):
name = models.CharField(max_length=32, unique=True)
affiliation = models.ForeignKey(Affiliation)
我的views.py
:
def add_banner(request):
if request.method == 'POST':
#some code here
else:
options = Options.objects.get(id=1)
print(options.new_affiliation.all()) #controll
choices = options.new_affiliation.all()
print(choices) #controll
form = BannerForm(choices, initial={
#some code regarding other fields
})
return render(request, 'core/add_banner.html', {'form': form})
我的add_banner.html
:
<form role="form" id="banner_form" enctype="multipart/form-data "method="post" action="../add_banner/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.label }}
{{ field }}
{{ field.help_text }}
<br />
{% endfor %}
我们将不胜感激任何帮助。
已更新。我只改了 views.py
:
def add_banner(request):
if request.method == 'POST':
#some code here
else:
options = Options.objects.get(id=1)
print(options.new_affiliation.all()) #controll
choices = tuple(options.new_affiliation.all())
print(choices) #controll
form = BannerForm(choices, initial={
#some code regarding other fields
})
return render(request, 'core/add_banner.html', {'form': form})
但是还是报错
更新 2。如果我直接从 form.py 传递选择,它会起作用:
我的 views.py
:
def add_banner(request):
if request.method == 'POST':
#some code here
else:
form = BannerForm(request.POST or None, initial={
#some code regarding other fields
})
return render(request, 'core/add_banner.html', {'form': form})
我的forms.py
:
class BannerForm(forms.ModelForm):
options = Options.objects.get(id=1)
choices = options.new_affiliation.all()
name = forms.CharField(max_length=32)
affiliation = forms.ModelChoiceField(choices)
不幸的是,这会在第一次迁移时出现问题(见上文)。
我正在尝试使用一些初始化方法来传递选择...
我的forms.py
:
class BannerForm(forms.ModelForm):
name = forms.CharField(max_length=32)
affiliation = forms.ModelChoiceField(choices)
def __init__(self, *args, **kwargs):
options = Options.objects.get(id=1)
choices = options.new_affiliation.all()
#choices = kwargs.pop('choices')
super(RegentForm, self).__init__(*args, **kwargs)
self.fields['affiliation'] = choices
但它说选择是不确定的
从我在这里看到的情况来看,您似乎收到了一个错误 "too many values to unpack",因为您没有将 "choices" 作为正确的类型发送。 ChoiceField 仅将选择作为元组,如模型的 the documentation 所示。如果您希望基于 QuerySet 定义选择,则必须将其转换为可以解释为有效 "choices" 的元组。例如,在我的一个项目中,我需要准备一组年份作为元组,以便我可以允许用户从预先确定的年份列表中 select。我指定了以下函数来执行此操作:
def years():
response = []
now = datetime.utcnow()
for i in range(1900, now.year + 1):
response.append([i, str(i)])
return tuple(response)
由于元组是不可变的,因此仅根据原则转换它们通常不是一个好主意。但是,在这种情况下,作为一种衡量标准,您似乎有必要声明您可以接受这些陈述可能存在的可变性。
根据您的具体情况,您可以考虑这样做:
choices = tuple(options.new_affiliation.all().values())
我没有测试过这段代码,坦率地说,我对你的项目并不完全熟悉,可能在这个回复的某些部分有错误。因此,它可能需要进一步调整,但请尝试一下。根据您的错误,这绝对是程序当前中断的地方。如果您有任何进展,请在此处更新。
完成!
我的form.py
:
class BannerForm(forms.ModelForm):
name = forms.CharField(max_length=32, label='Nome')
def __init__(self, *args, **kwargs):
options = Options.objects.get(id=1)
choices = options.new_affiliation.all()
super(BannerForm, self).__init__(*args, **kwargs)
self.fields['affiliation'] = forms.ModelChoiceField(choices)
self.fields['affiliation'].initial = choices
class Meta:
model = Banner
我的views.py
:
def add_banner(request):
if request.method == 'POST':
#some code here
else:
form = BannerForm(request.POST or None, initial={
#some code here
})
return render(request, 'core/add_banner.html', {'form': form})
谢谢
我使用 Bannerform
形式通过 add_banner
视图(和模板)创建新的 Banner
对象。我使用 class Options
来确定在 Bannerform
(affiliation
字段)形式中允许哪些 affiliation
对象。
我正在尝试将选项从视图传递到表单,但它给了我 ValueError:要解压的值太多(预期为 2)
我的代码在 new_affiliation
是 ForeignKey 时有效,但现在我需要更多值。我想我必须在 views
中确定 'choices' 否则我会在第一次迁移时遇到问题(它似乎是从 models.py
而不是从 views.py
调用数据库表,所以如果我把 Options.objects.get(id=1)
放在 models.py
上,它会给出错误,因为表还不存在)。
我的form.py
:
from django import forms
from core.models import Options, Banner, Affiliation #somethings other
class BannerForm(forms.ModelForm):
name = forms.CharField(max_length=32)
affiliation = forms.ChoiceField('choices')
#affiliation = forms.ModelChoiceField('choices') #same error
class Meta:
model = Banner
exclude = (#some fields)
我的models.py
:
from django.db import models
from django.contrib.auth.models import User
from django import forms
class Options(models.Model):
new_affiliation = models.ManyToManyField('Affiliation')
#new_affiliation = models.ForeignKey('Affiliation') #this worked (with some changes in views)
class Affiliation(models.Model):
name = models.CharField(max_length=32, unique=True)
class Banner(models.Model):
name = models.CharField(max_length=32, unique=True)
affiliation = models.ForeignKey(Affiliation)
我的views.py
:
def add_banner(request):
if request.method == 'POST':
#some code here
else:
options = Options.objects.get(id=1)
print(options.new_affiliation.all()) #controll
choices = options.new_affiliation.all()
print(choices) #controll
form = BannerForm(choices, initial={
#some code regarding other fields
})
return render(request, 'core/add_banner.html', {'form': form})
我的add_banner.html
:
<form role="form" id="banner_form" enctype="multipart/form-data "method="post" action="../add_banner/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.label }}
{{ field }}
{{ field.help_text }}
<br />
{% endfor %}
我们将不胜感激任何帮助。
已更新。我只改了 views.py
:
def add_banner(request):
if request.method == 'POST':
#some code here
else:
options = Options.objects.get(id=1)
print(options.new_affiliation.all()) #controll
choices = tuple(options.new_affiliation.all())
print(choices) #controll
form = BannerForm(choices, initial={
#some code regarding other fields
})
return render(request, 'core/add_banner.html', {'form': form})
但是还是报错
更新 2。如果我直接从 form.py 传递选择,它会起作用:
我的 views.py
:
def add_banner(request):
if request.method == 'POST':
#some code here
else:
form = BannerForm(request.POST or None, initial={
#some code regarding other fields
})
return render(request, 'core/add_banner.html', {'form': form})
我的forms.py
:
class BannerForm(forms.ModelForm):
options = Options.objects.get(id=1)
choices = options.new_affiliation.all()
name = forms.CharField(max_length=32)
affiliation = forms.ModelChoiceField(choices)
不幸的是,这会在第一次迁移时出现问题(见上文)。
我正在尝试使用一些初始化方法来传递选择...
我的forms.py
:
class BannerForm(forms.ModelForm):
name = forms.CharField(max_length=32)
affiliation = forms.ModelChoiceField(choices)
def __init__(self, *args, **kwargs):
options = Options.objects.get(id=1)
choices = options.new_affiliation.all()
#choices = kwargs.pop('choices')
super(RegentForm, self).__init__(*args, **kwargs)
self.fields['affiliation'] = choices
但它说选择是不确定的
从我在这里看到的情况来看,您似乎收到了一个错误 "too many values to unpack",因为您没有将 "choices" 作为正确的类型发送。 ChoiceField 仅将选择作为元组,如模型的 the documentation 所示。如果您希望基于 QuerySet 定义选择,则必须将其转换为可以解释为有效 "choices" 的元组。例如,在我的一个项目中,我需要准备一组年份作为元组,以便我可以允许用户从预先确定的年份列表中 select。我指定了以下函数来执行此操作:
def years():
response = []
now = datetime.utcnow()
for i in range(1900, now.year + 1):
response.append([i, str(i)])
return tuple(response)
由于元组是不可变的,因此仅根据原则转换它们通常不是一个好主意。但是,在这种情况下,作为一种衡量标准,您似乎有必要声明您可以接受这些陈述可能存在的可变性。
根据您的具体情况,您可以考虑这样做:
choices = tuple(options.new_affiliation.all().values())
我没有测试过这段代码,坦率地说,我对你的项目并不完全熟悉,可能在这个回复的某些部分有错误。因此,它可能需要进一步调整,但请尝试一下。根据您的错误,这绝对是程序当前中断的地方。如果您有任何进展,请在此处更新。
完成!
我的form.py
:
class BannerForm(forms.ModelForm):
name = forms.CharField(max_length=32, label='Nome')
def __init__(self, *args, **kwargs):
options = Options.objects.get(id=1)
choices = options.new_affiliation.all()
super(BannerForm, self).__init__(*args, **kwargs)
self.fields['affiliation'] = forms.ModelChoiceField(choices)
self.fields['affiliation'].initial = choices
class Meta:
model = Banner
我的views.py
:
def add_banner(request):
if request.method == 'POST':
#some code here
else:
form = BannerForm(request.POST or None, initial={
#some code here
})
return render(request, 'core/add_banner.html', {'form': form})
谢谢