Search code examples
pythonhtmldjangopostgresqlpostgis

How to execute PostgreSQL query in Django


I am trying to fetch the PostgreSQL table onto HTML using Django, When I execute the spatial query in the query Tool of PostgreSQL I got the perfect results, but When I'm trying to execute the same script from Django getting all rows of data. Thank you for helping in advance.

SQL query which is working perfectly

SELECT *
    FROM jhk_schls as point,jhk_urban as polygon
WHERE ST_Within(point.geom, polygon.geom)

Django Script

def search(request):
    if request.method == "POST":
        first_layer = request.POST.get('first_layer')
        spati_func = request.POST.get('spa_func')
        second_layer = request.POST.get('secon_layer')
        within_fun = 'select * from' + " " + str(first_layer) + " " + 'as point,' + str(second_layer) + " " + 'as polygon' + " " + 'WHERE' + " " + str(spati_func)+'(point.geom, polygon.geom)'
        cursor = connection.cursor()
        cursor.execute(within_fun)
        data = cursor.fetchall()
        return render(request, 'geoit/search.html',{ 'data':data})
    return render(request,'geoit/search.html')

HTML

<span>Select Layer</span>
      <select name="first_layer">
     <option value="-1" disabled  selected >Please select</option>
     Layer<li><option value="jhk_schls">jhk_schls</option></li>
    </select>
  </br>
  <span>Spatial Functions</span>
<select name="spa_func">
     <option value="-1" disabled  selected >Please select</option>
     Layer<li><option value="ST_Within">ST_Within</option></li>
    </select>
</br>
<span>Select Layer</span>
<select name="secon_layer">

     <option value="-1" disabled  selected >Please select</option>
     Layer<li><option value="jhk_urban">jhk_urban</option></li>
     
    </select>
<input type="submit" value="submit">
          </p>
        </div>
</form>
            <button type="submit" value="submit"><i class="fa fa-search"></i>
            </button>
        </form>
        <p></p>
        <center>
            <table>
    
           
        {% for item in data %}
                  <tr>
                <td>{{ item.0 }}</td>
                <td>{{ item.2 }}</td>
                 
            </tr>
        {% endfor %}
    </table>
        </center>
```

Solution

  • In Django you would want to use the Django ORM to get data out of your database.

    In this case, please look at the 'within' function of geoquerysets:

    https://docs.djangoproject.com/en/3.1/ref/contrib/gis/geoquerysets/#within

    As a side note, the way you constucted the query in your view, passing parameters from the view directly into your query, opens you up for SQL injection attacks and can be quite dangerous. IF you would need to create SQL with input from query string parameters, please read up on how to do this safely: https://realpython.com/prevent-python-sql-injection/#passing-safe-query-parameters