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

时间:2018-04-11 01:53:54

标签: django django-forms

我有一个名为'service'的字段。它存储一组代表公司提供的服务的整数(1 =会计,2 =人力资源等)。将列表保存到“服务”字段后,我希望能够将其作为“初始”值传递给表单,以便用户可以看到他们之前选择的选项。

什么有效:

a)用户可以选择服务

b)服务作为整体列表保存到“服务”字段(例如[2,3,5])

什么行不通:

a)尽管“服务”包含一个整体列表,但表格中没有显示初始值。

model.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                                          

form.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)

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

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

forms.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

答案 1 :(得分:0)

我认为你的代码无法正常工作的原因是:

在views.py中:

services = user.baseservicesoffered.service

提供字符串作为服务的价值,例如' [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中。

答案 2 :(得分:0)

在您的表单中__init__尝试更改

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

self.initial['service'] = selectedservices

并确保selectedservices是一个整数列表(不是像choices这样的情侣列表,而不是带逗号的字符串。)

PS:如果您将选项存储为字符串而不是整数initial应该是字符串列表。

相关问题