Implementing a logical parser in django-query

It will be "long." I include as much code and explanations as possible ... I am not above metadata if necessary.

I am trying to implement a logical parser in a django request system. Where users can provide complex queries against tags that apply to samples. This is essentially part of the repository of scientific samples, where users can apply certain tags (type of tissue, studied diseases, etc.). They can then create persistent “baskets” of patterns defined by a logical query for these tags.

#models.py

class Sample(models.Model):
    name = models.CharField(max_length = 255)


class Tag(models.Model):
    name = models.CharField(max_length = 255)
    samples = models.ManyToManyField(Sample)

A quick example:
#example data:
Sample1 has TagA, TagB, TagC
Sample2 has       TagB, TagC, TagD
Sample3 has TagA,       TagC, TagD
Sample4 has       TagB

#example query:
'TagB AND TagC AND NOT TagD'

will return Sample1. To create a set of objects, Q()I use a crazy hub for the -val string:

def MakeQObject(expression):
    """
    Takes an expression and uses a crazy string-eval hack to make the qobjects.
    """
    log_set = {'AND':'&','OR':'|','NOT':'~'}

    exp_f = []
    parts = expression.split()
    #if there is a ) or ( then we can't use this shortcut
    if '(' in parts or ')' in parts:
        return None

    for exp in parts:
        if exp in log_set:
            exp_f.append(log_set[exp])
        else:
            exp_f.append("Q(tags__name__iexact = '%s')" % exp)
    st = ' '.join(exp_f)
    qobj = eval(st)
    return qobj

-, (). , : (TagA OR TagB) AND NOT TagD Sample1, Sample4, . " ", . , ~ 40 000 ~ 400 ( ~ 7 ), ~ 4 . , . , , , , .

?

+3
1

-, , , , . , db_index = True :

class Tag(models.Model):
    name = models.CharField(max_length = 255, db_index=True)
    samples = models.ManyToManyField(Sample)

-, Python, PyParsing PLY. , , , .

, , Fredrik Python.

+1

Source: https://habr.com/ru/post/1727321/


All Articles