我有一个名为“服务”的字段。它存储代表公司提供的服务的整数列表(1=会计,2=人力资源等)。将列表保存到“服务”字段后,我希望能够将其作为“初始”值传递到表单,以便用户可以看到他们之前选择的选项。
什么有效:
a) 用户可以选择服务
b) 服务作为整数列表保存到“服务”字段(例如 [2, 3, 5])
什么不起作用:
a) 尽管“service”包含一个整数列表,但表单中并未显示初始值。
模型.py
class BaseServicesOffered(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
service = models.CharField(max_length=255, default='', null=True, blank=True)
def __str__(self):
return self.user.username
表格.py
class BaseServicesOfferedForm(forms.ModelForm):
service = forms.MultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
selectedservices = kwargs.pop('selectedservices')
super(BaseServicesOfferedForm, self).__init__(*args, **kwargs)
self.fields['service'].choices = [(t.id, t.service) for t in AllServices.objects.filter(industrycode=user.userprofile.industry)]
self.fields['service'].initial = selectedservices
class Meta:
exclude = ('user',)
model = BaseServicesOffered
views.py
@login_required(login_url="/accounts/login/")
def baseservicesoffered(request):
try:
base_services_offered = BaseServicesOffered.objects.create(user=request.user)
except:
pass
user = request.user
services = user.baseservicesoffered.service
instance = get_object_or_404(BaseServicesOffered, user=user)
form = BaseServicesOfferedForm(request.POST or None, user=request.user, selectedservices=services, instance=instance)
if request.method == 'POST':
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
service = form.cleaned_data['service']
services = [int(i) for i in service]
instance.service = services
instance.save()
return redirect('/accounts/profile/')
else:
context = {'form': form}
return render(request, 'accounts/setup8.html', context)
context = {'form': form}
return render(request, 'accounts/setup8.html', context)
感谢您的帮助!
在你的表格中
__init__
尝试改变
self.fields['service'].initial = selectedservices
到
self.initial['service'] = selectedservices
并确保
selectedservices
是一个整数列表(不是像 choices
这样的成对列表,也不是带有逗号的字符串)。
PS:如果您将选择存储为字符串而不是整数,
initial
应该是字符串列表。
你几乎已经拥有它了。这是你应该做的:
表格.py
class BaseServicesOfferedForm(forms.ModelForm):
service = forms.MultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
**selectedservices = kwargs.pop('selectedservices')**
super(BaseServicesOfferedForm, self).__init__(*args, **kwargs)
self.fields['service'].choices = [(t.id, t.service) for t in AllServices.objects.filter(industrycode=user.userprofile.industry)]
self.fields['service'].initial = selectedservices**
class Meta:
exclude = ('user',)
model = BaseServicesOffered
我认为你的代码不起作用的原因是这样的:
在views.py中:
services = user.baseservicesoffered.service
给出一个string作为服务的值,例如'[2,3,5]'。然后将服务作为选定服务传递到您的表单中:
form = BaseServicesOfferedForm(request.POST or None, user=request.user, selectedservices=services, instance=instance)
在您的表单中,当您将 selectedservices 的值指定为服务的初始值时:
self.fields['service'].initial = selectedservices
一个字符串被分配给首字母,但没有像“[2,3,5]”这样的项目。您想要的是将值 2、3、5 中的每一个传递给初始值。
这里:
services = [int(i) for i in service]
instance.service = services
您正在尝试将列表保存到 CharField 中,该列表实际上被保存为“[2, 3, 5]”(您可以检查数据库表以确保)。
因此,您必须以某种方式将字符串 selectedservices 转换回表单中的列表,或者不要将列表保存到 CharField 中。
我正在处理同样的问题。 拥有带有 CheckboxSelectMultiple 小部件的 MultipleChoiceField 表单,并将数据保存为模型中的 CharField。
数据被保存为看起来像列表的文字字符串,但事实并非如此。 并且表单需要该字段的初始值列表。
将字符串转换为 python 列表可以实现像下面 view.py 中的代码片段这样的技巧
import ast
def land_demand_form(request):
obj= get_object_or_404(Contact, user=request.user)
res = ast.literal_eval(obj.prefered_contact)
form = ContactForm(request.POST or None, initial={"prefered_contact": res})
context= {'form': form}
查看此博客了解更多信息:这里