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

File django-safereprqueryset-in-debug.patch, 3.5 KB (added by kcarnold, 7 years ago)
  • db/models/query.py

     
    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

     
    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

     
    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)
Back to Top