N
N
NyxDeveloper2021-01-21 11:56:02
Django
NyxDeveloper, 2021-01-21 11:56:02

How to implement a search with remembering previous queries?

I do a search on the table, above each column of which there is a search form for each field of the model (each column). The search works fine, but you need to add something like a cache so that the previous search parameters are saved. Because the search and sort function is universal for each model, I want to make caching universal. Previously, a model corresponding to the table model was used to create the cache.
Example:
cache model

class CacheContact(models.Model):
    user = models.CharField('user', max_length=200, default='')
    firstName = models.CharField('Имя', max_length=150, blank=True, default='')
    lastName = models.CharField('Фамилия', max_length=150, blank=True, default='')
    middleName = models.CharField('Отчество', max_length=150, blank=True, default='')
    idContr = models.CharField('Контрагент', max_length=150, blank=True, default='')
    idDolj = models.CharField('Должность', max_length=150, blank=True, default='')
    description = models.TextField('Примечание', max_length=2000, blank=True)

    class Meta:
        verbose_name = 'Контакт'
        verbose_name_plural = 'Контакты'

    def __str__(self):
        return self.firstName + ' ' + self.middleName + ' ' + self.lastName


real object model
#   контакт
class Contact(models.Model):
    firstName = models.CharField('Имя', max_length=150)
    lastName = models.CharField('Фамилия', max_length=150)
    middleName = models.CharField('Отчество', max_length=150, blank=True)
    idContr = models.ForeignKey(Kontragent, verbose_name='Контрагент', on_delete=models.SET_NULL, null=True)
    idDolj = models.ForeignKey(Dolj, verbose_name='Должность', on_delete=models.SET_NULL, null=True)
    description = models.CharField('Примечание', max_length=2000, blank=True)

    class Meta:
        verbose_name = 'Контакт'
        verbose_name_plural = 'Контакты'

    def __str__(self):
        return self.firstName + ' ' + self.middleName + ' ' + self.lastName


There were a lot of such models, because. in fact, each table model had to be duplicated and all fields replaced with CharField. I want to do something more versatile, like storing the previous query as a string or an object and retrieving parameters from there for each table. I don’t know yet how exactly to do this, maybe there is already a ready-made solution, or maybe someone will tell you how it would be better to implement such an object, or maybe not an object, but a function that works in real time. The search and sort function looks like this:
def search_and_sort(request, list, instance, cache_instance):
    #   перебор всех параметров, переданных в request.GET
    for setting in request.GET:
        #   проверка на параметр сортировки
        if setting == 'sorted' or setting == 'resort':
            #   если нужно отсортировать от большего к меньшему
            if setting == 'sorted' and request.GET.get(setting) is not '':
                list = list.order_by('-'+request.GET.get(setting))
            #   если нужно отсортировать от меньшего к большему
            else:
                list = list.order_by(request.GET.get(setting))
        #   если это параметр поиска
        else:
            #   список полей переданного объекта
            if request.GET.get(setting) is None or request.GET.get(setting) is '':
                continue
            fields = instance._meta.get_fields()
            for field in fields:
                if field.name == setting:
                    #   если имя поля совпадает с параметром поиска фильтруем список по значению из параметра поиска
                    #   и выходим из цикла чтобы экономить время
                    if field.many_to_one or field.one_to_many:
                        filter_kwargs = {'%s__id' % field.name: request.GET.get(setting)}
                    else:
                        filter_kwargs = {'%s__icontains' % field.name: request.GET.get(setting)}

                    list = list.filter(**filter_kwargs)
                    break
    return list


You need to give it a cache object as a parameter, check whether there are new fields in the current request or not, if not, then take the fields from the cache, and if so, then replace the parameters in the cache with the fields from the request. Can you please tell me how can I implement this functionality?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question