加载编辑视图时显示多选项目

Show multi-selected itens when load a edit view

我正在为一些数据做一个编辑表单。我在将信息传递给时遇到问题。正如您在我看来看到的那样,我使用“初始”字典将数据传递给表单。

VIEWS.PY

@login_required
def project_detail(request, project_id):
    if request.method == 'POST':
        project = get_object_or_404(Project, pk=project_id)
        form = ProjectDetailForm(project_id, request.POST, instance = project)        
        if form.is_valid():
            instance = form.save(commit=False)
            instance.client = Project.objects.get(pk=project_id).client
            form.save()
            messages.success(request,'Projeto modificado')
            return redirect('projects')
        else:
            messages.error(request,'Ocorreu um erro!')
    else:
        project = get_object_or_404(Project, pk=project_id)
        form = ProjectDetailForm(project_id, initial={'modal':project.modal,
                                                    'culture':project.culture,
                                                    'owner':project.owner,
                                                    'value':project.value,
                                                    'final_date':project.final_date,
                                                    'text':project.text,
                                                    'status':project.status,
                                                    'farm':project.farm.values()})
    return render(request,'project_detail.html',{'form':form})

但是这样做,数据并没有显示在.想到这里,ManyToManyField 将数据保存在列表中。我尝试迭代此字段但仍然无法正常工作,我想这不是执行此操作的最佳方法。

MODELS.PY

class Project(models.Model):
    modal_types = [('CUSTEIO AGRÍCOLA','Custeio Agrícola'),('CUSTEIO PECUÁRIO','Custeio Pecuário'),('INVESTIMENTO AGRÍCOLA','Investimento Agrícola'),('INVESTIMENTO PECUÁRIO','Investimento Pecuário'),('FGPP','FGPP')]
    status_opts = [('Análise','Análise'),('Desenvolvimento','Desenvolvimento'),('Processamento','Processamento'),('Liberação','Liberação'),('Finalizado','Finalizado'),('Cancelado','Cancelado'),('Suspenso','Suspenso')]
    farm = models.ManyToManyField(Farm, related_name='farm_name',verbose_name='Propriedade beneficiada')
    client = models.ForeignKey(Clients, on_delete=models.CASCADE, related_name='project_client',default=None,null=True, verbose_name='Cliente')
    owner = models.ForeignKey(Owner, on_delete=models.CASCADE, related_name='project_bidder',default=None,null=True, verbose_name='Proponente')
    warranty = models.ManyToManyField(Farm, related_name='project_warranty',default=None, verbose_name='Propriedade de garantia')
    modal = models.CharField(max_length=100,default=None,choices=modal_types, null=True, verbose_name='Tipo')
    culture = models.CharField(max_length=50,null=True, verbose_name='Cultura')
    status = models.CharField(max_length=50,null=True, verbose_name='Status', choices=status_opts)
    created_date = models.DateField(null=True, verbose_name='Data de criação')
    value = models.FloatField(max_length=10,null=True, verbose_name='Valor financiado')
    final_date = models.DateField(default=None,null=True, verbose_name='Fim do contrato')
    text = models.TextField(default=None,null=True, verbose_name='Observações')

forms.py

class ProjectDetailForm(ModelForm):
    
    class Meta:
        model = Project
        fields = ['status','owner', 'farm', 'warranty', 'modal', 'culture', 'value','final_date','text']

    def __init__(self, project_id, *args, **kwargs):
        client_id = Project.objects.get(pk=project_id).client
        super(ProjectDetailForm,self).__init__(*args,**kwargs)
        self.fields['value'].required = False
        self.fields['final_date'].required = False
        self.fields['text'].required = False
        self.fields['farm'].queryset = Farm.objects.filter(client=client_id)
        self.fields['warranty'].queryset = Farm.objects.filter(client=client_id)
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'

这里是所有带信息的字段,但在“select”中没有任何内容 selected,尽管数据库中有数据

有人可以帮助我吗?

为什么要将 'project_id' 传递到表单 class 实例中?尝试改变这个:

form = ProjectDetailForm(project_id, request.POST, instance = project)

对此:

form = ProjectDetailForm(request.POST, instance = project)

看看是否有帮助。同样在您的表单初始化中,我不确定您是否正确使用了“initial =”值字典。初始值通常是适用于“创建”视图的默认值,而不是您希望在更新视图中看到的数据库记录。我想你想在那里传递你的数据库记录的实例,比如:

    else:
        project = get_object_or_404(Project, pk=project_id)
        form = ProjectDetailForm(instance=project)

此外,您真的不需要在此视图中编写两次项目对象查询。你可以这样做:

def project_detail(request, project_id):
    project = get_object_or_404(Project, pk=project_id) # query this once here
    if request.method == 'POST':
        form = ProjectDetailForm(request.POST, instance=project)        
        if form.is_valid():
            instance = form.save(commit=False)
            instance.client = Project.objects.get(pk=project_id).client
            form.save()
            messages.success(request,'Projeto modificado')
            return redirect('projects')
        else:
            messages.error(request,'Ocorreu um erro!')
            # you probably want a redirect here as well
    else:
        form = ProjectDetailForm(instance=project)

    return render(request,'project_detail.html',{'form':form})

最后,如果您试图限制用户表单中 ManyToMany 字段的选择,您可以这样做:

class ProjectDetailForm(forms.ModelForm):

    class Meta:
        model = YourModelName
        fields = ['farm']

        farm = forms.ModelMultipleChoiceField(
        queryset=Farm.objects.filter(some_field=some_criteria).order_by('some_field'),
        widget=forms.CheckboxSelectMultiple)

有关表单 classes here in Django docs.

上的小部件的更多信息