简体   繁体   中英

Use django-filters on multiple models

I'm trying to create a search capability in my Django project that will filter multiple models (currently 3) and return a value from the surveys model. It works for a single model and an additional model tied by a foreign key. But, when I added a dropdown menu for the third model not containing a direct reference to the initial model, I got an error saying they keyword was unavailable (because it wasn't looking in the model):

Cannot resolve keyword 'rooms' into field. Choices are: DateBegin, FAN, IS, Location, PI, holdings, id

Models:

#models.py
class rooms(models.Model):
    ContainerLocation = models.CharField(max_length=100, blank=True, null=True)
    Database = models.CharField(max_length=100, blank=True, null=True)
    Name = models.CharField(max_length=100, blank=True, null=True)
    Datatype = models.CharField(max_length=100, blank=True, null=True)

class holdings(models.Model):
    Contents = models.CharField(max_length=700, blank=True, null=True, default='No description')
    FAN = models.ForeignKey('surveys', on_delete=models.SET_NULL, blank=True, null=True)
    Database = models.ForeignKey('rooms', on_delete=models.SET_NULL, blank=True, null=True)
    ...(more fields)...

class surveys(models.Model):    
    FAN = models.SlugField(max_length=100, blank=True, null=True)
    PI = models.CharField(max_length=100, blank=True, null=True)
    IS = models.CharField(max_length=100, blank=True, null=True)
    DateBegin = models.DateField(blank=True, null=True)
    Location = models.CharField(max_length=200, blank=True, null=True)  

Filter:

#filters.py
from django import forms
from datalibrary.models import surveys, rooms, holdings
import django_filters

class MultiFilter(django_filters.FilterSet):
    FAN = django_filters.CharFilter(lookup_expr='icontains', distinct=True)
    PI = django_filters.CharFilter(lookup_expr='icontains', distinct=True)
    Location = django_filters.CharFilter(lookup_expr='icontains', distinct=True)
    Contents = django_filters.CharFilter(field_name='holdings__Contents', lookup_expr='icontains', label='Contents', distinct=True)
    Room = django_filters.ModelChoiceFilter(queryset=rooms.objects.all(), label='Room', distinct=True)

    class Meta:
        model = surveys
        fields = ['FAN', 'PI', 'Location', 'Contents', 'Room']

Views:

#views.py
def search(request):
    multifilter = MultiFilter(request.GET, queryset=surveys.objects.all())
    return render(request, 'search_results.html', {'filter': multifilter})

Is it possible to build a filter with django-filters that searches multiple models? Can I create a merged queryset or something like that? I tried adding a list to the filters Meta (eg model = [surveys, rooms, holdings] ) but that obviously doesn't work.

If django-filters can't do it, are there other options for searching multiple models in Django?

I figured out how this should work. Another model can be specified using modelname__field (that's two underscores)in the fields variable under Meta . So it would look like this:

#filters.py
from django import forms
from datalibrary.models import surveys, rooms, holdings
import django_filters

class MultiFilter(django_filters.FilterSet):
    FAN = django_filters.CharFilter(lookup_expr='icontains', distinct=True)
    PI = django_filters.CharFilter(lookup_expr='icontains', distinct=True)
    Location = django_filters.CharFilter(lookup_expr='icontains', distinct=True)
    Contents = django_filters.CharFilter(field_name='holdings__Contents', lookup_expr='icontains', label='Contents', distinct=True)
    Room = django_filters.ModelChoiceFilter(lookup_expr='icontains', label='Room', distinct=True)

    class Meta:
        model = surveys
        fields = ['FAN', 'PI', 'Location', 'Contents', 'rooms__name']

rooms__name here is referring to the field name in the model rooms .

Note that changed Room to rooms_name .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM