2010-05-28 4 views
7

Descargo de responsabilidad: Todavía estoy aprendiendo Django, por lo que podría estar perdiendo algo aquí, pero no puedo ver lo que sería ...Posible error de Django en QuerySet.query?

Estoy ejecutando Python 2.6.1 y Django 1.2.1.

(InteractiveConsole) 
>>> from myproject.myapp.models import * 
>>> qs = Identifier.objects.filter(Q(key="a") | Q(key="b")) 
>>> print qs.query 
SELECT `app_identifier`.`id`, `app_identifier`.`user_id`, 
`app_identifier`.`key`, `app_identifier`.`value` FROM 
`app_identifier` WHERE (`app_identifier`.`key` = a OR 
`app_identifier`.`key` = b) 
>>> 

¡Observe que no pone comillas alrededor de "a" o "b"! Ahora, he determinado que la consulta ejecuta bien. Entonces, en realidad, debe estar haciéndolo. Pero es bastante molesto que la impresión de la consulta se imprima mal. Especialmente si he hecho algo como esto ...

>>> qs = Identifier.objects.filter(Q(key=") AND") | Q(key="\"x\"); DROP TABLE  
       `app_identifier`")) 
>>> print qs.query 
SELECT `app_identifier`.`id`, `app_identifier`.`user_id`, 
`app_identifier`.`key`, `app_identifier`.`value` FROM 
`app_identifier` WHERE (`app_identifier`.`key` =) AND OR 
`app_identifier`.`key` = "x"); DROP TABLE `app_identifier`) 
>>> 

Lo cual, como se puede ver, no sólo crea el código SQL completamente mal formado, pero también tiene las semillas de un ataque de inyección SQL. Ahora, obviamente esto no funcionaría, por una serie de razones (1. La sintaxis es totalmente incorrecta, intencionalmente, para mostrar la rareza del comportamiento de Django. 2. Django no ejecutará la consulta de esta manera, lo hará en realidad poner comillas y barras y todo eso como se supone que debe).

Pero, esto realmente hace que la depuración sea confusa, y me hace preguntarme si algo salió mal con mi instalación de Django.

¿Esto le sucede? Si es así/no, ¿qué versión de Python y Django tienes?

¿Alguna idea?

+1

¿has probado 'qs.query.as_sql()'? – Amarghosh

+1

Según tengo entendido, QuerySet.query.as_sql() ya no funciona como una versión de Django anterior a 1.2.1. He entrado en el mundo de Django usando 1.2.1, así que no conozco todos los detalles, pero en mi investigación sobre este tema eso fue lo que descubrí. "print qs.query.as_sql()" hace que "AttributeError: el objeto 'Query' no tenga el atributo 'as_sql'" en mi instalación. – MikeC8

Respuesta

9

Ok, acabo de descubrirlo. No es un error. Navegar por la fuente de Django/db/modelos/sql/query.py:

160  def __str__(self): 
161   """ 
162   Returns the query as a string of SQL with the parameter values 
163   substituted in. 
164 
165   Parameter values won't necessarily be quoted correctly, since that is 
166   done by the database interface at execution time. 
167   """ 
168   sql, params = self.get_compiler(DEFAULT_DB_ALIAS).as_sql() 
169   return sql % params 

(http://code.djangoproject.com/browser/django/trunk/django/db/models/sql/query.py)

todo funciona correctamente. :)

+0

Gran pregunta y respuesta (No supe esto por cierto después de más de un año trabajando con Django). Esto es algo sobre lo que he tenido dudas durante un tiempo, pero me imaginé que me faltaba algo. Ahora sé que. ¡Gracias! –