Django

Code

Ticket #6748: django-safereprqueryset-in-debug.patch

File django-safereprqueryset-in-debug.patch, 3.5 kB (added by kcarnold, 10 months ago)
  • db/models/query.py

    old new  
    11851185            setattr(instance, cls._meta.pk.attname, None) 
    11861186 
    11871187    transaction.commit_unless_managed() 
     1188 
     1189 
     1190class SafeReprQuerySet(QuerySet): 
     1191    """ This QuerySet class will be safe to `repr`. 
     1192    That means: 
     1193        1. If the QuerySet object passed is already evaluated, repr will behave as before. 
     1194        2. If the QuerySet object has not been evaluated, repr will be the SQL. 
     1195 
     1196    Example usage:: 
     1197 
     1198        >>> if isinstance(qs, QuerySet): 
     1199        >>>     qs = SafeReprQuerySet.from_queryset(qs) 
     1200        >>> print repr(qs) 
     1201    """ 
     1202 
     1203    @classmethod 
     1204    def from_queryset(cls, queryset): 
     1205        """ Take a queryset and create a SafeReprQuerySet from it. """ 
     1206        assert isinstance(queryset, QuerySet), "from_queryset requires a QuerySet object, recieved %r" % queryset 
     1207        new_queryset = queryset._clone(klass=cls, _result_cache=queryset._result_cache) 
     1208        new_queryset._old_class = queryset.__class__ 
     1209        return new_queryset 
     1210 
     1211 
     1212    def __repr__(self): 
     1213        """ Return a representation of this object that doesn't evaluate the SQL. """ 
     1214        old_class = self._old_class.__name__ 
     1215        if self._result_cache: 
     1216            return QuerySet.__repr__(self) 
     1217 
     1218        try: 
     1219            select, sql, params = self._get_sql_clause() 
     1220            sql = ("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql) 
     1221            try: 
     1222                return '<%s SQL:%r>' % (old_class, sql % tuple(params)) 
     1223            except: 
     1224                return '<%s SQL:%r>' % (old_class, [sql, params]) 
     1225        except: 
     1226            return '<%s object>' % old_class 
  • views/debug.py

    old new  
    463463                {% for var in frame.vars|dictsort:"0" %} 
    464464                  <tr> 
    465465                    <td>{{ var.0|escape }}</td> 
    466                     <td class="code"><div>{{ var.1|pprint|escape }}</div></td> 
     466                    <td class="code"><div>{{ var.1|safe_pprint|escape }}</div></td> 
    467467                  </tr> 
    468468                {% endfor %} 
    469469              </tbody> 
  • template/defaultfilters.py

    old new  
    790790        return u"Error in formatting: %s" % force_unicode(e, errors="replace") 
    791791pprint.is_safe = True 
    792792 
     793def safe_pprint(value): 
     794    """A wrapper around pprint that ensures that QuerySets don't get evaluated. 
     795    If the QuerySet results have already been used, they will be cached and the 
     796    result will be identical to normal pprint. However, if the QuerySet has not 
     797    been used, this filter will return the SQL that the QuerySet would execute.""" 
     798    from django.db.models.query import QuerySet, SafeReprQuerySet 
     799    if isinstance(value, QuerySet) and not isinstance(value, SafeReprQuerySet): 
     800        value = SafeReprQuerySet.from_queryset(value) 
     801    return pprint(value) 
     802     
     803 
    793804# Syntax: register.filter(name of filter, callback) 
    794805register.filter(add) 
    795806register.filter(addslashes) 
     
    828839register.filter(random) 
    829840register.filter(rjust) 
    830841register.filter(safe) 
     842register.filter(safe_pprint) 
    831843register.filter('slice', slice_) 
    832844register.filter(slugify) 
    833845register.filter(stringformat)