Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

149
Visualizações
Cómo crear consultas dinámicas con objetos Django Q desde paréntesis dentro de una cadena

No sé si el título de la pregunta está lo suficientemente bien formado. Pero esencialmente me gustaría poder hacer algo como esto desde el frente:

 (name="abc" OR name="xyz") AND (status="active" OR (status="available" AND age=30))

Quiero que el usuario envíe esta cadena. Lo analizaré en backend y formaré una consulta.

Miré this answer y this pero no pude encontrar la manera de resolver el paréntesis aquí.

Estoy pensando en usar una pila (la forma en que resolvemos las expresiones infijas) para hacer esto, pero no quiero seguir ese camino largo a menos que esté seguro de que no hay otra solución lista disponible. Si alguien puede hacer esto con ese método, también sería genial.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Creo que será algo como esto.

 YourModel.objects.filter( Q(Q(name="abc") | Q(name="xyz")) & Q( Q(status="active") OR Q(Q(status="available") & Q(age=30) ) ) )
over 4 years ago · Santiago Trujillo Relatório

0

Así que lo hice cambiando un poco el 'solucionador de expresiones infijas'.

Aquí está el código:

 def complex_filter_by_string(mystr): """ Filters string by using Q objects and infix expression solver. The input string should be of the type ( name = abc OR name = xyz ) AND ( other = fgh ) Or ( other_one = xyz ) Notice the spaces after each 'word'. We are splitting the string by space, so space is necessary. """ tokens = mystr.split() # stack to store integer values. values = [] # stack to store operators. ops = [] i = 0 while i < len(tokens): # Current token is a whitespace, # skip it. if tokens[i] == ' ': i += 1 continue # Current token is an opening # brace, push it to 'ops' elif tokens[i] == '(': ops.append(tokens[i]) # Current token is =, convert it to a Q object and push # it to stack for q objects. elif tokens[i] == "=": # if token equals '=' . It means we will have tokens[i-1]=attribute and tokens[i+1]=value (this is a constraint on string) obj = {} key = tokens[i-1] value = tokens[i+1] if isinstance(value,str): i+=1 while i+1 < len(tokens) and (tokens[i+1] != 'OR' and tokens[i+1] != 'AND' and tokens[i+1] != ')'): value= value + " " + tokens[i+1] i+=1 value = value.rstrip() obj[key]=value val = Q(**obj) values.append(val) # Closing brace encountered, # solve entire brace. elif tokens[i] == ')': while len(ops) != 0 and ops[-1] != '(': val2 = values.pop() val1 = values.pop() op = ops.pop() values.append(applyOp(val1, val2, op)) # pop opening brace. ops.pop() # Current token is an operator. elif tokens[i] == "OR" or tokens[i] == "AND": # While top of 'ops' has same or # greater precedence to current # token, which is an operator. # Apply operator on top of 'ops' # to top two elements in values stack. while (len(ops) != 0 and precedence(ops[-1]) >= precedence(tokens[i])): val2 = values.pop() val1 = values.pop() op = ops.pop() values.append(applyOp(val1, val2, op)) # Push current token to 'ops'. ops.append(tokens[i]) i += 1 # Entire expression has been parsed # at this point, apply remaining ops # to remaining values. while len(ops) != 0: val2 = values.pop() val1 = values.pop() op = ops.pop() values.append(applyOp(val1, val2, op)) # Top of 'values' contains result, # return it. return values[-1]

Esto devolverá un objeto Q que puede pasar a su modelo miente MyModel.objects.filter(q_obj)

Sin embargo, hay algunas restricciones en la cadena. La restricción principal es 'debe haber un espacio en blanco después de cada palabra clave'. Una palabra clave puede ser 'OR, AND, atributo, valor, =, paréntesis abierto'.

Entonces, la cadena que publiqué en cuestión debería ser: ( name = abc OR name = xyz ) AND (status = active OR ( status = available AND age = 30 ))

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda