将列表传递到 MultipleChoiceField 表单作为初始值

问题描述 投票:0回答:4

我有一个名为“服务”的字段。它存储代表公司提供的服务的整数列表(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)

感谢您的帮助!

django django-forms
4个回答
2
投票

在你的表格中

__init__
尝试改变

self.fields['service'].initial = selectedservices

self.initial['service'] = selectedservices

并确保

selectedservices
是一个整数列表(不是像
choices
这样的成对列表,也不是带有逗号的字符串)。

PS:如果您将选择存储为字符串而不是整数,

initial
应该是字符串列表。


0
投票

你几乎已经拥有它了。这是你应该做的:

表格.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

0
投票

我认为你的代码不起作用的原因是这样的:

在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 中。


0
投票

我正在处理同样的问题。 拥有带有 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}

查看此博客了解更多信息:这里

© www.soinside.com 2019 - 2024. All rights reserved.