Format data queryset result to use in form.ModelChoiceField queryset option

Hi,

I’m working in Django project that is conencted with Postgres database.

Now i’m doing some test because i’m not an expect with Django.

I want to create a form with a ModelChoiceField where I can select the data obtained in a previous queryset.

In the forms.py file i have these 2 queryset:

lista_queryset_nombres_all = BdimMaestraDatos.objects.values_list(‘nombre’).filter(fecha_baja__isnull=True).distinct()

lista_queryset_nombres_activos_values = BdimMaestraDatos.objects.filter(estado=1).values(‘nombre’).distinct()

The result of both are:

<QuerySet [('PEDRO',), ('JUAN',), ('ANDRES',), ('PABLO',), ('SOFIA',)]>
<QuerySet [{'nombre':'PEDRO'}, {'nombre':'JUAN'}, {'nombre':'ANDRES'}, {'nombre':'PABLO'}, {'nombre':'SOFIA'}]>

So when I want to show the result into the select input (forms.ModelChoiceField) template, the info or data is showed “dirty” format, like parenthesis, coma, etc. and only want show the names.

Please, How can I do it that in the forms.ModelChoiceField only appears the names PEDRO, JUAN, PABLO, etc and not (‘PEDRO’,), (‘JUAN’,), etc.?

This is my forms.py file

from django import forms
from .models import BdimMaestraDatos, BdimMaestraEquipos

lista_queryset_nombres_all = BdimMaestraDatos.objects.values_list('nombre').filter(fecha_baja__isnull=True).distinct()
print('Resultado Queryset ALL: %s' %lista_queryset_nombres_all)
lista_queryset_nombres_activos_values = BdimMaestraDatos.objects.filter(estado=1).values('nombre').distinct()
print('Resultado Queryset values: %s' %lista_queryset_nombres_activos_values)

class MaestraDatosForm(forms.Form):
    Seleccionar_Nombre = forms.ModelChoiceField(label="Nombre", queryset=lista_queryset_nombres_activos_values)

This is my BdimMaestraDatos model.

nombre = models.CharField(db_column='NOMBRE', max_length=32, blank=True, null=True)  # Field name made lowercase.
cc = models.CharField(db_column='CC', max_length=2, blank=True, null=True)  # Field name made lowercase.
estado = models.DecimalField(db_column='ESTADO', max_digits=1, decimal_places=0, blank=True, null=True)  # Field name made lowercase.
red = models.CharField(db_column='RED', max_length=32, blank=True, null=True)  # Field name made lowercase.
ger = models.CharField(db_column='GER', max_length=32, blank=True, null=True)  # Field name made lowercase.
est = models.TextField(db_column='EST', blank=True, null=True)  # Field name made lowercase. This field type is a guess.
fecha_baja = models.DateField(db_column='FECHA_BAJA', blank=True, null=True)  # Field name made lowercase.
fecha_alta = models.DateField(db_column='FECHA_ALTA', blank=True, null=True)  # Field name made lowercase.

Thanks

ModelChoiceField is used to create a relation between the form and a single instance of a model. The queryset is used to select which model instances are offered, from which the user can select one.

In your queryset, when you used values() you tell the queryset to return dictionaries instead of instances. The ModelChoiceField expects instances, which is why you get different results from what you expect.

By using distinct() you are also grouping the returned values together, which now makes it impossible to have a 1:1 relation between a model instance and what option the user selects in the form.

If you want to limit the names a user can choose from to distinct names that are in your table, then you would want to use a normale ChoiceField with the choices= parameter set to choices=BdimMaestraDatos.objects.values_list('nombre', 'nombre').filter(fecha_baja__isnull=True).distinct()

@doom,

Thanks for reply i will try this that you tell me.

By other side, I solved the problem using ModelChoiceField. In that case I add the argument flat=True inside the values_list queryset. Like this:

lista_queryset_nombres_all = BdimMaestraDatos.objects.values_list(‘nombre’, flat=True).filter(fecha_baja__isnull=True).distinct()

After that the result of lista_queryset_nombres_all is that one:

<QuerySet ['PEDRO', 'JUAN', 'ANDRES', 'PABLO', 'SOFIA']>

Thanks again!