Adithya
Adithya

Reputation: 1857

How to add custom view in django adminlte?

I created an environment using pycharm & installed adminlte by git clone from https://github.com/app-generator/django-dashboard-adminlte.git. And installed adminlte3 , django3.1 & all requirements. Then run python manage.py runserver and registered a new user & was able to login ,view all pages, added new link to a html page. But I am unable to add view with jsonresponse to a button click on new page, geting Error 500 - Server Error.

My new html page is

{% extends "layouts/base.html" %}
{% block title %} Layout Boxed {% endblock %} 
<!-- Element injected in the BODY element -->
{% block body_class %} sidebar-mini layout-boxed {% endblock body_class %} 
<!-- Specific Page CSS goes HERE  -->
{% block stylesheets %}
  <!-- Google Font: Source Sans Pro -->
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
  <!-- Font Awesome -->
  <link rel="stylesheet" href="/static/assets/plugins/fontawesome-free/css/all.min.css">
  <!-- Theme style -->
  <link rel="stylesheet" href="/static/assets/css/adminlte.min.css">
  <link rel="stylesheet" href="/static/assets/css/mapstyle.css">
  <link rel="stylesheet" href="/static/assets/js/pages/gis/dist/map.css">
<style>
   .map {
        margin: 0;
        padding: 0;
        width: 900px;
        height: 500px;
        background:white !important;
    border:1px solid #ccc;
      }
</style>
{% endblock stylesheets %}
{% block content %}
  <div class="content-wrapper">
    <div id="lyrDiv"></div>
    <div id="map" class="map"></div>
    <button id="search">Search</button>
  </div>
{% endblock content %}
<!-- Specific Page JS goes HERE  -->
{% block javascripts %}
  <!-- jQuery -->
  <script src="/static/assets/plugins/jquery/jquery.min.js"></script>
  <!-- Bootstrap 4 -->
  <script src="/static/assets/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
  <!-- AdminLTE App -->
  <script src="/static/assets/js/adminlte.min.js"></script>
  <!-- AdminLTE for demo purposes -->
  <script src="/static/assets/js/demo.js"></script>
  <script src="/static/assets/js/pages/map.js"></script>
  <script src="/static/assets/js/pages/search.js"></script>
{% endblock javascripts %}

search.js

$( "#search" ).click(function() {
    $.get('/search/',{'csrfmiddlewaretoken':csrftoken},function(data){
        alert(data); // here getting Error 500 - Server Error
    });
});

I added below line to /django-dashboard-adminlte/app/urls.py

re_path(r'^search/$', search.spatial_srch, name='search'), 

and search.py

from app.models import *
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse

@csrf_exempt
def spatial_srch(request):
    data= Demotable.objects.all() 
    searchArr = []
    output = {}

    for c in data:
        searchArr.append({'type': 'Feature', 'properties': {'id':c.id,'name': str(c.name)},'geometry': {'type': 'Point', 'coordinates': [c.the_geom.x, c.the_geom.y]}})
    output = {'type': 'FeatureCollection', 'features': searchArr}
    return JsonResponse(output)

When I click on the 'Serach' button the request is not going to the view search.py What is wrong in my code ? what configuration did I miss?

The post shows enter image description here

The Error 500 shows only adminlte Error page. Nothing more enter image description here

Upvotes: 1

Views: 1209

Answers (1)

user1600649
user1600649

Reputation:

The problem is in the (not so nice) way they generate the error. It's anti-pattern hell there, but in short it means there's an except thrown in either:

  • finding the template
  • loading the template
  • or rendering the template

and they catch it and don't let you see what happened. Not very nice code and you're have to modify that file to even begin debugging it:

@login_required(login_url="/login/")
def pages(request):
    context = {}
    # All resource paths end in .html.
    # Pick out the html file name from the url. And load that template.
    try:
        
        load_template = request.path.split('/')[-1]
        html_template = loader.get_template( load_template )
        return HttpResponse(html_template.render(context, request))
        
    except template.TemplateDoesNotExist:

        html_template = loader.get_template( 'page-404.html' )
        return HttpResponse(html_template.render(context, request))

    # Remove or comment these lines:
    #except:
    #
    #   html_template = loader.get_template( 'page-500.html' )
    #    return HttpResponse(html_template.render(context, request))

Also I'm not sure this the specific spot where the error is generated, they might be doing similar things in other places.

Edit

This is very .... unprofessional code:

    # Matches any html file
    re_path(r'^.*\.*', views.pages, name='pages'),

No, it doesn't not match any "html" file - it matches everything cause they don't get regular expressions:

^ - start of string
.* - anything or nothing
\.* - >>>zero<<< or more dots

Result: \.* is ignored as it is irrelevant so it matches everything and if you placed your re_path below it, it will never be consulted, because Django uses first match wins approach.

So your url matches theirs, which then routes it to pages view:

load_template = request.path.split('/')[-1]

Since request.path is '/search/', '/search/'.split('/')[-1] gives the empty string and that creates your problem.

I highly suggest fixing their url path:

    # Matches any html file
    re_path(r'\.html$', views.pages, name='pages'),

Or put your re_path above theirs.

Upvotes: 3

Related Questions