How to filter items in the Foreign key field of the Django form?

Asked

Viewed 479 times

0

Good evening! I’m new to python/djagno, and I’m new to the community, too, that’s my first question.

What I want to do is filter the items from a selection list of a Foreign key (Template) on the plate registration screen.

Ex.: Show only what is True in the Active column of the table

register.py (models)

class Cadastro_placas(models.Model):
Numero_serie = models.CharField(
    'Número de série',
    max_length=120
)

Modelo = models.ForeignKey(
    'placas.modelo_placas', 
    related_name='modelo_placas_modelo',
    on_delete = models.PROTECT,
    null = True,
)

Revisao_lm = models.IntegerField(
    'Revisao LM'
)

Lote_numero = models.ForeignKey(
    'placas.cadastro_lote',
    related_name='numero_lote',
    on_delete = models.PROTECT
)

Observacao = models.TextField(
    'Observação',
    blank=True
)

def __str__(self):
    return self.Numero_serie

class Meta:
    db_table = 'CADASTRO_PLACAS'
    constraints = [
        models.UniqueConstraint(fields=['Numero_serie'], name="Constraint_placas")
    ]

model_boards (models)

class Modelo_placas(models.Model):
Modelo = models.CharField(
    'modelo',
    max_length=120
)

Descricao = models.CharField(
    'Descrição',
    max_length=200
)

Ativo = models.BooleanField(
    'Modelo Ativo',
    default=True
)



def __str__(self):
    return '{} - {}'.format(self.Modelo, self.Descricao) 

class Meta:
    db_table = 'MODELO_PLACAS'
    constraints = [
        models.UniqueConstraint(fields=['Modelo', 'Descricao'], name="Constraint_modelo")
    ]

cadastrar_placa (views)

def cadastrar_placa(request):
context = {
    "form": PlacaForm       
}
if request.method == "POST":
    form = PlacaForm(request.POST)
    if form.is_valid():
        form.save()      
return render(request, "placas/cadastrar-placa.html", context)

Forms.py (form)

class ModeloForm(forms.ModelForm):
class Meta:
    model = Modelo_placas
    fields = '__all__'

class PlacaForm(forms.ModelForm):
    class Meta:
        model = Cadastro_placas
        fields = '__all__'

register-board.html (html)

                    <form method="POST" class="post-form ">
                    {% csrf_token %}
                    <div class="form-row">
                        <div class="form-group col-md-8 mb-xl-1">
                            {{ form.Numero_serie  | as_crispy_field:"bootstrap"}}
                            {{ form.Revisao_lm | as_crispy_field:"bootstrap" }}
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-8 mb-xl-1">
                            {{ form.Lote_numero  | as_crispy_field:"bootstrap"}}
                        </div>
                        <div class="form-group col-md-1 mb-xl-0 ">
                            <a href="#"><img src="{% static 'placas/images/acrescer-png.png' %}" alt="+ lote"
                                    width=15 height=15 data-toggle="modal" data-target="#loteModal"></a>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-8 mb-xl-4">
                            {{ form.Modelo | as_crispy_field:"bootstrap"}}
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-8 mb-xl-4">
                            {{ form.Observacao | as_crispy_field:"bootstrap"}}
                        </div>
                    </div>
                    <button type="submit" class="save btn btn-outline-primary col-md-8 mb-3  ">Salvar</button>
                </form>

2 answers

1


I was able to solve my problem by placing the attribute limit_choices_to in the model field of the table Cadastro_placas, leaving the field as code below:

class Cadastro_placas(models.Model):   
Modelo = models.ForeignKey(
    'placas.modelo_placas', 
    related_name='modelo_placas_modelo',
    on_delete = models.PROTECT,
    null = True,
    limit_choices_to= {'Ativo': True} #Limita somente a modelos ativos
)

With this I got that appear only the models that are classified True in the Active field.

0

Vc can call the filter in Modelo_plates to get the list of active cards and then a for to fetch the respective entries

from .models import Modelo_placas, Cadastro_placas

def list_placas():
    modelos_ativos = Modelo_placas.filter(ativo=True) #retorna uma lista com as ocorrencias

    placas_ativas = []
    for modelo in modelos_ativos:
        placas_ativas.append(Cadastro_placas.objects.get(Modelo=modelo))
    data = {
        "placas":placas_ativas 
         }
    return render(request,'listaplacas', data)

  • From what I understood of your answer, this I would do in the view, but how do I put this return to the field Model that is in the table of registration.py? For it is in this field that I want only active models to appear.

  • As far as I know, the Foreignkey registry doesn’t have that kind of validation. Once you have referenced a table, at first all items in that table can be registered. What can be done and the control on your frontend, being done this validation before performing Submit. You can also in the view function itself perform this validation before you save. One last solution, which I think is not good, is to make a table with only the active ones. In this case , she would have only one field that would be precisely the Foreignkey of Model_plates and in Cadastre_plateswould receive the Foreignkey of this auxiliary table

Browser other questions tagged

You are not signed in. Login or sign up in order to post.