I have a working function that populates a dropdown with the emails of all registered tutors. The problem is that when a new Tutor is registered, it gets redirected to the home template (where the form filter is rendered), but the dropdown with the choices is not updated, even if I hit refresh. It gets updated after in VisualStudio I stop the server and run again runserver, or press ctrl + s and the server is reloaded. I figured out that the function get_tutores() is only called once, and what I want to achieve is to call that function from the views every time the page is reloaded.
MODEL
class Tutor(models.Model):
user = models.OneToOneField(
User, on_delete=models.CASCADE, primary_key=True)
nombre = models.CharField(max_length=50, blank=False, null=True)
apellido = models.CharField(max_length=50, blank=False, null=True)
biografia = models.TextField()
curriculum = models.FileField(upload_to="curriculums/", blank=True, null=True)
foto = models.ImageField(blank=True, null=True)
carrera = models.ManyToManyField(Carrera, blank=True)
linea_invest = models.ManyToManyField(Linea_Invest, blank=True)
correo = models.EmailField(blank=True, null=True)
numero_celular = models.CharField(max_length=20, blank=True, null=True)
class Meta:
verbose_name_plural = "Tutores"
verbose_name = "Tutor"
def __str__(self):
return '%s %s' % (self.nombre, self.apellido)
FILTER:
def get_tutores():
tutores = []
for tut in Tutor.objects.all():
tutores.append((tut.user.id,tut.user.email,))
return tutores
class TutorFilter(django_filters.FilterSet):
nombre = CharFilter(field_name="nombre", label="Nombre",lookup_expr='icontains')
apellido = CharFilter(field_name="apellido", label="Apellido",lookup_expr='icontains')
carrera = ModelMultipleChoiceFilter(field_name= "carrera", queryset= Carrera.objects.all())
user = ChoiceFilter( label = "correo", choices=get_tutores())
class Meta:
model = Tutor
fields = ("nombre", "apellido", "carrera","user")
VIEWS
def home(request):
tutores = Tutor.objects.all()
filtro_tutor = TutorFilter(request.GET, queryset=tutores)
tutores = filtro_tutor.qs
context = {
'tutores': tutores , 'filtro_tutor': filtro_tutor
}
return render(request, 'home.html', context)
TEMPLATE
<section class="section">
<div class="container">
<div class="columns ">
<div class="column ">
<div class="field is-grouped is-small ">
<div class="control ">
<form method="get">
{{ filtro_tutor.form }}
<div class="control">
<button class="button is-link" type="submit">
Buscar
</button>
</div>
</div>
</form>
</div>
<div>
{% for obj in filtro_tutor.qs %}
{{ obj.correo }} - ${{ obj.user }}<br />
{% endfor %}
</div>
</div>
</div>
</div>
</section>
Tryed to do this in the home view:
filtro_tutor['user'].extra['choices'] = get_tutores()
But got "TutorFilter' object is not subscriptable"
It looks like your user = ChoiceFilter(…)
is in essence a ModelMultipleChoiceFilter
, but where you specify a different field_class
that uses the email
of the user, and a queryset
that filters the users by Tutor
:
from django import forms
class UserModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return str(obj.email)
class UserModelMultipleChoiceFilter(ModelMultipleChoiceFilter):
field_class = UserModelChoiceField
class TutorFilter(django_filters.FilterSet):
# …
user = UserModelMultipleChoiceFilter(
queryset=User.objects.filter(tutor__isnull=False)
)