title: Django: SQL Injection-proof managers.py
body: <p>I have a managers.py file that uses the .extra() parameter to perform raw SQL queries. For example:</p>
  
  <pre><code>class MyManager(models.Manager):
  
      def order_null_last(self, field):
          return super(DecisionManager, self).get_query_set()\
              .extra(select={'has_field': "CASE WHEN " + field + " IS NULL THEN 1 ELSE 0 END"}).order_by('has_field', field)
  </code></pre>
  
  <p>It's been suggested to me that this kind of query could be vulnerable to attack by injection.</p>
  
  <p>The variable 'field' is parsed to make sure it belongs to a group of legitimate values, but this checking is done in the view. Eg:</p>
  
  <pre><code>class ModelList(ListView):
      model = MyModel
  
      def get(self, request, *args, **kwargs):
          self.set_sorting(request)
  
      def set_sorting(self, request):
          self.sort_field = request.GET.get('sort', '-id')
          if not self.sort_field in self.sort_options:
              self.sort_field = 'id'
  </code></pre>
  
  <p>So if someone wrote a new view using the above manager but they forgot to filter the parameters then the exploit would be possible.</p>
  
  <p>So, is there a way to validate a parameter against a models fields in the manager without getting circular imports? That is, the manager needs to import the model to get a list of permitted fields, but the model needs to import the manager.</p>