3
respostas

Popular um Select

Olá, estou com dúvidas de como preencher um select a partir de uma consulta do banco:

def cargo(request, id):
    cargo = get_object_or_404(Cargo,pk=id)
    record = {
        'cargo' : cargo
    }
    return render(request,'cargo.html', record)
def cargo_new(request):
    records = Setor.objects.all()
    setores = {
        'setores' : records
    }
    return render(request,'cargo.html', setores)

Na página html está assim:

<select class="custom-select" name="setor" id="setor">
    {% for setor in setores %}
        <option value="{{ setor.id }}">{{ setor.nome }}</option>
    {% endfor %}
</select>

Para preencher um novo registro o select carrega corretamente, porém na edição não está carregando nada.

class Cargo(models.Model):
    nome = models.CharField(max_length=50, unique=True, blank=False)
    setor = models.ForeignKey(Setor, on_delete=models.CASCADE)
    vagas = models.PositiveIntegerField(default=0, blank=True, null=True)
    def __str__(self):
        return self.nome

As urls acredito que está correto:

urlpatterns = [
    path('cargos',views.cargos,name='cargos'),
    path('cargo/<int:id>',views.cargo,name='cargo'),
    path('cargo/save',views.cargo_save,name='cargo_save'),
    path('cargo',views.cargo_new,name='cargo_new'),
    path('cargo/<int:id>/delete',views.cargo_delete,name='cargo_delete'),
]

Se tiver alguma forma mais simples/recomendável de fazer o CRUD por favor me avisem.

3 respostas

Tentei:

def cargo(request, id):
    cargos_sql = get_object_or_404(Cargo,pk=id)
    setores_sql = Setor.objects.all().order_by('nome')
    cargos = {
        'cargo' : cargos_sql
    }
    setores = {
        'setores' : setores_sql
    }
    resultado = {'cargo':cargo,'setores':setores}
    return render(request,'cargo.html',resultado)

porém ainda não deu certo, acho que a solução deve ser simples, porém não acho nenhum exemplo, alguém pra me dar um norte??

A única forma que consegui fazer funcionar foi:

def cargo_new(request):
    records = Setor.objects.all().order_by('nome')
    setores = {
        'setores' : records
    }
    return render(request,'cargo.html', {'s':setores})
def cargo(request, id):
    cargos_sql = get_object_or_404(Cargo,pk=id)
    setores_sql = Setor.objects.all().order_by('nome')
    cargo = {
        'cargo' : cargos_sql
    }
    setores = {
        'setores' : setores_sql
    }
    return render(request,'cargo.html',{'c':cargo,'s':setores})
def cargo_save(request):  # METODO USADO PARA CRIAR E ATUALIZR REGISTRO
    if request.method == 'POST':
        id = request.POST['id']
        nome = request.POST['nome']
        setor = request.POST['setor']
        s = get_object_or_404(Setor,pk=setor)

        if id == '':
            p = Cargo.objects.create(nome=nome,setor=s)
        else:
            Cargo.objects.filter(pk=id).update(nome=nome,setor=s)
        return redirect('cargos')
    else:
        return redirect('404')
<select class="custom-select" name="setor" id="setor">
     {% for setor in s.setores %}
    <option value="{{ setor.id }}" {% if setor.id == c.cargo.setor.id %} selected{%endif %}>{{ setor.nome }}</option>
    {% endfor %}
</select>

Porém acho que deve ser uma forma mais simples de fazer isso...

Oii Rafael, como você está?

Sinto muito pela demora em obter um retorno.

Como você não especificou o porque não estava dando certo, ficou um pouco incerto saber o motivo que estava ocasionando, se era algum erro ou se apenas não conseguia obter o resultado esperado.

Quanto ao código que você apresentou, ao invés de utilizar dois dicionários e utilizar um terceiro para passar para o context, você pode passar os dados em apenas um, tendo como chave cargo e setores. Por exemplo:

resultado = {
        'cargo' : cargos_sql,
        'setores' : setores_sql
    }
return render(request,'cargo.html', resultado)

Outro ponto seria ter um método apenas para salvar e outro para atualizar, que é o mais comum de se ver, até por questão de dividir melhor as responsabilidades do código.

Qualquer dúvida estou por aqui, tá bom?

Abraços e bons estudos!