Home > Software engineering >  Show multi-selected itens when load a edit view
Show multi-selected itens when load a edit view

Time:02-26

I'm doing a edit form for some data. I'm having problem to pass information to . As you can see in my view, I pass the data to form using "initial" dictionary.

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})

But doing this, the data is not displaied in . Thinking here, ManyToManyField saves data in lists. I tried iterate this field but still not working and I guess thats not the best way to do this.

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'

Here all the fields with information, but in "select" nothing is selected, despite having data in the database enter image description here

Someone can help me?

CodePudding user response:

Why are you passing 'project_id' into your form class instance? Try changing this:

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

to this:

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

and see if it helps. Also in your form initialization, I'm not sure you're using the "initial=" values dictionary correctly. Initial values are typically defaults applicable to the "create" view, not database records that it sounds like you want to see in an update view. I think you want to pass in the instance of your database record there, something like:

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

Also, you really don't need to write project object query twice in this view. You can do something like:

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})

Finally, if you're trying to limit the choices from your ManyToMany field in the user's form, you can do so with something like this:

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)

More info about widgets on form classes here in Django docs.

  • Related