python_wiki:django_configuration

This is an old revision of the document!


Django Configuration

General Information

Configuring the Django Web Framework and its dependencies.

Checklist


Database: MariaDB

Configuring the MariaDB Database.

  • Configure MariaDB to listen only on localhost
    vim /etc/my.cnf
     
    [mysqld]
    bind-address=127.0.0.1
  • Start/Enable the database
    systemctl enable mariadb
    systemctl start mariadb
  • Run secure setup
    mysql_secure_installation
    • Prompts for the following:
      • Set database root password
      • Remove anonymous users
      • Disallow root logins remotely
      • Remove test databases
      • Reload privilege tables
  • Connect to the database
    mysql -u root -p
  • Create your project's database
    create database myprojecthere character set utf8;
  • Create a database user that Django will use
    create user appuserhere@localhost identified by 'PASSWORDHERE';
  • Grant permissions for the app user on your project's database
    grant all privileges on myprojecthere.* to appuserhere@localhost;
  • Flush privileges
    flush privileges;

Django

Configuring Django.

  • Verify django works
    python
    >>> import django
    >>> print(django.get_version())
    >>> exit()
  • Create a directory to store the project
    mkdir /home/django
    cd /home/django
  • Create a new Django project
    django-admin startproject myprojecthere
    cd /home/django/myprojecthere
  • Create a new Django application inside of the project
    python manage.py startapp myapphere
  • Edit project settings (/home/django/myprojecthere/myprojecthere/settings.py)
    # Allowed Referrer Hosts (hostname and any cnames)
    ALLOWED_HOSTS = ['djangoserver.mycorps.domain.org','myapp.mycorps.domain.org']
     
    # Application definition (add the application, the rest are built in)
    INSTALLED_APPS = [
         # APPNAME.apps.APPCLASSNAME -> see ../myapphere/apps.py
        'myapphere.apps.MyapphereConfig',    # add your application here
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]
     
    # Static files (CSS, JavaScript, Images)
    #https://docs.djangoproject.com/en/1.11/howto/static-files/
    STATIC_URL = '/static/'
    STATIC_ROOT = '/var/www/static/'
  • Edit project settings (/home/django/myprojecthere/myprojecthere/settings.py)
    # Database Configuration
    # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'myprojecthere',
            'USER': 'appuserhere',
            'PASSWORD': 'PASSWORDHERE',
            'HOST': '127.0.0.1',
            'PORT': '3306',
            'OPTIONS': {
                  'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
            },
        }
    }
  • Run the initial migrate command to create database tables for built in apps that come with Django
    cd /home/django/myprojecthere
    python manage.py migrate
  • Describe your data models (objects that will be stored in the database) (/home/django/myprojecthere/myapphere/models.py) EXAMPLE
    # -*- coding: utf-8 -*-                                                                                                                                            
    from __future__ import unicode_literals
    from django.db import models
     
    # Asset Inventory Example
    class AssetEntry(models.Model):
     
      ##-- Tuples for Use in Field Choices --##
     
      #asset_type choices
      DEVICE_TYPES = ( 
        ('Firewalls', 'Firewalls'), 
        ('Routers', 'Routers'), 
        ('Servers', 'Servers'), 
        ('Storage', 'Storage'), 
        ('Switches', 'Switches'), 
        ('Workstations', 'Workstations'),
      )
     
      # asset_env choices 
      ENV_NAMES = ( 
        ('Dev', 'Development'), 
        ('Test', 'Testing'), 
        ('Prod', 'Production'),
      )
     
      # Linux OS List
      OS_NAMES_LINUX = ( 
        ('CentOS 6', 'CentOS 6'), 
        ('CentOS 7', 'CentOS 7'), 
        ('RHEL 6', 'Red Hat Enterprise Linux 6'), 
        ('RHEL 7', 'Red Hat Enterprise Linux 7'), 
        ('Ubuntu 16.04', 'Ubuntu 16.04'), 
        ('Ubuntu 18.04', 'Ubuntu 18.04'), 
      )
     
      # Windows OS List
      OS_NAMES_WINDOWS = ( 
        ('Win 2008', 'Windows 2008'), 
        ('Win 2012', 'Windows 2012'), 
        ('Win 2016', 'Windows 2016'), 
        ('Win 7', 'Windows 7'), 
        ('Win 10', 'Windows 10'),
      )
     
      # Other OS List
      OS_NAMES_OTHER = ( 
        ('Cisco IOS', 'Cisco IOS'), 
        ('Extreme XOS', 'Extreme XOS'), 
        ('Juniper JunOS', 'Juniper JunOS'), 
        ('NA', 'None'), 
        ('Other', 'Other'), 
        ('VMware ESXi', 'VMware ESXi'), 
      )
     
      # Combined OS List - for asset_os choices
      OS_NAMES = OS_NAMES_LINUX + OS_NAMES_WINDOWS + OS_NAMES_OTHER
     
      # asset_hardware choices 
      HW_TYPES = (
        ('Virtual', 'Virtual'), 
        ('Physical', 'Physical'),
      )
     
      ##-- AssetEntry Fields --##
      asset_name = models.CharField('Name', max_length=50)
     
      asset_type = models.CharField('Device Type', max_length=15, choices=DEVICE_TYPES)
     
      asset_description = models.CharField('Description', max_length=100)
     
      asset_env = models.CharField('Environment', max_length=15, choices=ENV_NAMES)
     
      asset_os = models.CharField('OS Name/Version', max_length = 20, choices=OS_NAMES)
     
      asset_hardware = models.CharField('Hardware: Virtual or Physical', max_length = 15, choices=HW_TYPES)
     
      # Object representation
      def __str__(self):
        return self.asset_name
  • Stage changes to the database
    cd /home/django/myprojecthere
    python manage.py makemigrations myapphere
  • Make changes to the database
    cd /home/django/myprojecthere
    python manage.py migrate
  • Edit project settings (/home/django/myprojecthere/myprojecthere/settings.py)
    # Logging Configuration
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'verbose': {
                'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
                'datefmt' : "%d/%b/%Y %H:%M:%S",
            },
            'simple': {
                'format': '%(levelname)s %(message)s',
            },
        },
        'handlers': {
            'file': {
                'level': 'INFO',
                'class': 'logging.handlers.RotatingFileHandler',
                'filename': '/var/log/myprojecthere/myapphere.log',
                'maxBytes': 500000000, # 500 MB
                'backupCount': 10,
                'formatter': 'verbose',
            },
        },
        'loggers': {
            'django': {
                'handlers': ['file'],
                'level': 'INFO',
                'propagate': True,
            },
            'myapphere': {
                'handlers': ['file'],
                'level': 'INFO',
            },
        },
    }
    ####---- End of Logging Config ----####
  • Create logging directory and setup ownership/permissions
    mkdir /var/log/myprojecthere
    chown :apache /var/log/myprojecthere
    chmod g+rwx /var/log/myprojecthere
  • Create an admin user
    python manage.py createsuperuser
  • Make your models/objects available for editing in the admin portal (/home/django/myprojecthere/myapphere/admin.py)
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
     
    from django.contrib import admin
     
    # Register your models here.
     
    # Make Class Available in Admin Portal (see /home/django/myprojecthere/myapphere/models.py)
    from .models import AssetEntry
    admin.site.register(AssetEntry)

A URL+View will generate a web page.

Project Level URLs File

  • Edit project URLs (/home/django/myprojecthere/myprojecthere/urls.py)
     # add the "import include" part or you won't be able to refer to app level url files
    from django.conf.urls import url, include
    from django.contrib import admin
     
    # URL Regex Patterns - Map URIs to App's url file for additional matching
    urlpatterns = [
        # No URI following site name (default app to use)
        url(r'^$', include('myapphere.urls')),
        # URI for app's name
        url(r'^myapphere/', include('myapphere.urls')),
        # Included /admin URI
        url(r'^admin/', admin.site.urls),
    ]


App Level URLs File

  • Create a new App level URLs file (/home/django/myprojecthere/myapphere/urls.py) EXAMPLE
    # urls.py - App URLs Map to App Views
    from django.conf.urls import url
     
    from . import views
     
    urlpatterns = [
      # "/myapphere/" beginning is implied because we are in the "myapphere" urls file already
     
      # /myapphere/  -  All Devices, All Environments (the index)
      url(r'^$', views.index, name='index'),
     
      # /myapphere/stats  -  All Devices, Statistics
      url(r'^stats/$', views.stats, name='stats'),
     
      # /myapphere/env_name  -  All Devices, Specific Environment
      url(r'^(?P<env_name>(dev|test|prod))/$', views.env, name='env'),
     
      # /myapphere/device/  - Specific Device, All Environments
      url(r'^(?P<device>(servers|workstations|switches|routers|firewalls))/$', views.device, name='device'),
     
      # /myapphere/device/env_name  -  Specific Device, Specific Environment
      url(r'^(?P<device>(servers|workstations|switches|routers|firewalls))/(?P<env_name>(dev|test|prod))/$', views.device_env, name='device_env'),
    ]
  • Edit the App Views that are loaded depending upon URL match(/home/django/myprojecthere/myapphere/views.py) EXAMPLE
    # views.py - URLs are mapped to views
    # -*- coding: utf-8 -*-                                                                                       
    from __future__ import unicode_literals                                                                              
     
    # Render http response+templates
    from django.shortcuts import render
     
    # Object or 404
    from django.shortcuts import get_object_or_404
     
    # HTTP Response
    from django.http import HttpResponse
     
    # Logging
    import logging
    logger = logging.getLogger(__name__)
     
    # Your Apps Model
    from .models import AssetEntry
     
    # /myapphere/  -  All Devices, All Environments (the index)
    def index(request):
      # Get all asset objects
      all_asset_list = AssetEntry.objects.order_by('asset_type', 'asset_env', 'asset_name')
     
      # Get number of assets in list
      number_assets = len(all_asset_list)
     
      # Map template variable names (1st) to Python variables (2nd) for use in html templates
      context = { 'all_asset_list': all_asset_list, 'asset_count': number_assets }
     
      # Logging
      logger.info("Rendering index.html - All Devices, All Environments")
     
      # Render the http request, using the template, passing the context
      return render(request, 'myapphere/index.html', context)
     
     
    # /myapphere/stats  -  All Devices, Statistics
    def stats(request):
      # Get all asset objects
      all_asset_list = AssetEntry.objects.order_by('asset_type', 'asset_env', 'asset_name')
     
      # Get all asset device types
      asset_type_list = [key for key,value in AssetEntry.DEVICE_TYPES]
     
      # Get all os names, Linux only, Windows only
      os_list = [key for key,value in AssetEntry.OS_NAMES]
      os_list_linux = [key for key,value in AssetEntry.OS_NAMES_LINUX]
      os_list_windows = [key for key,value in AssetEntry.OS_NAMES_WINDOWS]
     
      # Log for debug purposes
      #for key in os_list:
      #  logger.info("Field names are: " + key)
     
      #- Build Statistics -#
      # Initialize Stats list (will be a list of dictionaries)
      stats_list = []
     
      ####---- Asset Counts Table: Grand Total Row ----####
      sysstats_grand_total = 0
      sysstats_grand_physical = 0
      sysstats_grand_physical_linux = 0
      sysstats_grand_physical_windows = 0
      sysstats_grand_physical_other = 0
      sysstats_grand_virtual = 0
      sysstats_grand_virtual_linux = 0
      sysstats_grand_virtual_windows = 0
      sysstats_grand_virtual_other = 0
      sysstats_grand_vmware = 0
     
      # Calculate stats for each type of device
      for device_type in asset_type_list:
        # Initialize an empty device stats list
        device_stats = []
     
        # Add node to the device_stats list if a node from the all_asset_list matches the current device type
        for node in all_asset_list:
          if ''.join(node.asset_type.lower().split()) == device_type.lower():
            device_stats.append(node)
     
        ####---- Asset Counts Table ----#### 
        # Total Count
        count_total = len(device_stats)
     
        #- Add to grand total
        sysstats_grand_total += count_total
     
        # Physical and Virtual Counts
        count_physical = 0
        count_physical_linux = 0
        count_physical_windows = 0
        count_physical_other = 0
        count_virtual = 0
        count_virtual_linux = 0
        count_virtual_windows = 0
        count_virtual_other = 0
        for node in device_stats:
          if node.asset_hardware == "Physical":
            count_physical += 1
     
            if node.asset_os in os_list_linux:
              # Physical+Linux Count
              count_physical_linux += 1
            elif node.asset_os in os_list_windows:
              # Physical+Windows Count
              count_physical_windows += 1
            else:
              # Physical+Other OS
              count_physical_other += 1
     
          elif node.asset_hardware == "Virtual":
            # Virtual Count
            count_virtual += 1
     
            if node.asset_os in os_list_linux:
              # Virtual+Linux Count
              count_virtual_linux += 1
            elif node.asset_os in os_list_windows:
              # Virtual+Windows Count
              count_virtual_windows += 1
            else:
              # Virtual+Other OS
              count_virtual_other += 1
     
        #- Add to grand total physical
        sysstats_grand_physical += count_physical
        sysstats_grand_physical_linux += count_physical_linux
        sysstats_grand_physical_windows += count_physical_windows
        sysstats_grand_physical_other += count_physical_other
     
        #- Add to grand total virtual
        sysstats_grand_virtual += count_virtual
        sysstats_grand_virtual_linux += count_virtual_linux
        sysstats_grand_virtual_windows += count_virtual_windows
        sysstats_grand_virtual_other += count_virtual_other
     
        ####---- OS Counts Table ----####
        # Initialize a new empty OS Counts List
        os_counts = []
     
        # Add all the os names and an initial count of 0
        for name in os_list:
          os_counts.append({ 'os_name': name, 'count': 0 })
     
        # Check each node in the devices specific stats
        for node in device_stats:
          # Compare node's OS against each os name in the os_counts list and increment count if a match is found
          for os_entry in os_counts:
            if os_entry['os_name'] == node.asset_os:
              # Increment count value on an os name match
              os_entry['count'] += 1
     
     
        ####---- After All Stats Calculations: Add Device Stats to stats_list ----####
        # Add device statistics to stats_list
        stats_list.append({ 'asset_type': device_type, 'total': count_total, 'physical': count_physical, 'physical_linux': count_physical_linux, 'physical_windows': count_physical_windows, 'physical_other': count_physical_other, 'virtual': count_virtual, 'virtual_linux': count_virtual_linux, 'virtual_windows': count_virtual_windows, 'virtual_other': count_virtual_other, 'os_count_stats': os_counts })
     
        # Grand Total Only: VMware ESXi Host Count
        for node in device_stats:
          if node.asset_os.startswith("VMware"):
            sysstats_grand_vmware += 1
      #-- END OF Calculate Device Type Stats loop --#
     
      ##-- Calculate OS stats grand totals --##
     
      # Initialize a new empty OS Counts Total List
      os_counts_total = []
     
      # Add all the os names and an initial count of 0
      for name in os_list:
        os_counts_total.append({ 'os_name': name, 'count': 0})
     
      # For each device specific stats entry, add up grand total os counts
      for device_entry in stats_list:
        # For each device_entry in the stats_list, go through its os_count_stats value, which is a list of os_names and counts
        for os_device_entry in device_entry['os_count_stats']:
          # Check each os_count_stats os_name against the os_counts_total os_name list
          for os_entry_total in os_counts_total:
            # If we have an os_name match, add the device's os count to the total os count
            if os_entry_total['os_name'] == os_device_entry['os_name']:
              os_entry_total['count'] += os_device_entry['count']
     
      ####---- Add grand totals to stats_list ----####
      stats_list.append({ 'asset_type': 'Total', 'total': sysstats_grand_total, 'physical': sysstats_grand_physical, 'physical_linux': sysstats_grand_physical_linux, 'physical_windows': sysstats_grand_physical_windows, 'physical_other': sysstats_grand_physical_other, 'virtual': sysstats_grand_virtual, 'virtual_linux': sysstats_grand_virtual_linux, 'virtual_windows': sysstats_grand_virtual_windows, 'virtual_other': sysstats_grand_virtual_other, 'os_count_stats': os_counts_total })
     
      #- Other Grand Totals: Calculate -#
      sysstats_grand_linux = sysstats_grand_physical_linux + sysstats_grand_virtual_linux
      sysstats_grand_windows = sysstats_grand_physical_windows + sysstats_grand_virtual_windows
      sysstats_grand_other = sysstats_grand_physical_other + sysstats_grand_virtual_other
     
      # Map template variable names (1st) to the Python variables (2nd) for use in templates
      context = {'device_stats': stats_list, 'total_linux': sysstats_grand_linux, 'total_windows': sysstats_grand_windows, 'total_other': sysstats_grand_other, 'total_vmware': sysstats_grand_vmware, 'os_list': os_list}
     
      # Logging
      logger.info("Rendering stats.html")
     
      # Render the HTTP request, using the template, passing the context
      return render(request, 'myapphere/stats.html', context)
     
     
    # /myapphere/env_name  -  All Devices, Specific Environment
    def env(request, env_name):
      # Get all asset objects
      all_asset_list = AssetEntry.objects.order_by('asset_type', 'asset_env', 'asset_name')
     
      # New List for the asset types in the passed environment only
      new_list = []
     
      # Check each asset, add to new list if it matches the requested environment name
      for node in all_asset_list:
        if ''.join(node.asset_env.lower().split()) == env_name.lower():
          new_list.append(node)
     
      # Get number of assets in list
      number_assets = len(new_list)
     
      # Map template variable names (1st) to Python variables (2nd) for use in html templates
      context = { 'all_asset_list': new_list, 'env': env_name, 'asset_count': number_assets }
     
      # Logging
      logger.info("Rendering index.html - All Devices, " + env_name)
     
      # Render the http request, using the template, passing the context
      return render(request, 'myapphere/index.html', context)
     
     
    # /myapphere/device/  - Specific Device, All Environments
    def asset_type_all_env(request, device_type):
      # Get all asset objects
      all_asset_list = AssetEntry.objects.order_by('asset_type', 'asset_env', 'asset_name')
     
      # New List for specific devices only
      new_list = []
     
      # Check each asset, add to new list if it matches the requested device type
      for node in all_asset_list:
        if ''.join(node.asset_type.lower().split()) == device_type.lower():
          new_list.append(node)
     
      # Get number of assets in list
      number_assets = len(new_list)
     
      # Map template variable names (1st) to Python variables (2nd) for use in html templates
      context = { 'all_asset_list': new_list, 'asset_type': device_type, 'asset_count': number_assets }
     
      # Logging
      logger.info("Rendering index.html - Devices: " + device_type + ", All Environments")
     
      # Render the http request, using the template, passing the context
      return render(request, 'myapphere/index.html', context)
     
     
    # /myapphere/device/env_name  -  Specific Device, Specific Environment
    def type_env(request, device_type, env_name):
      # Get all asset objects
      all_asset_list = AssetEntry.objects.order_by('asset_type', 'asset_env', 'asset_name')
     
      # New List for specific devices and environment only
      new_list = []
     
      # Check each asset, add to new list if it matches the requested device and environment
      for node in all_asset_list:
        if ''.join(node.asset_type.lower().split()) == device_type.lower():
          if ''.join(node.asset_env.lower().split()) == env_name.lower():
            new_list.append(node)
     
      # Get number of assets in list
      number_assets = len(new_list)
     
      # Map template variable names (1st) to Python variables (2nd) for use in html templates
      context = { 'all_asset_list': new_list, 'asset_type': device_type, 'env': env_name, 'asset_count': number_assets }
     
      # Logging
      logger.info("Rendering index.html - Devices: " + device_type + ", Env: " + env_name)
     
      # Render the http request, using the template, passing the context
      return render(request, 'myapphere/index.html', context)
     
     
    # /myapphere/<asset_hardware>/  - Physical or Virtual
    def asset_hardware(request, asset_hardware):
      # Get all asset objects
      all_asset_list = AssetEntry.objects.order_by('asset_type', 'asset_env', 'asset_name')
     
      # New List for asset_hardware (physical or virtual)
      new_list = []
     
      # Check each asset, add to new list if it matches the requested hardware type
      for node in all_asset_list:
        if ''.join(node.asset_hardware.lower().split()) == asset_hardware.lower():
          new_list.append(node)
     
      # Get number of assets in list
      number_assets = len(new_list)
     
      # Map template variable names (1st) to the Python variables (2nd) for use in templates
      context = {'all_asset_list': new_list, 'asset_hardware': asset_hardware, 'asset_count': number_assets }
     
      # Logging
      logger.info("Rendering index.html - All Devices, " + asset_hardware)
     
      # Render the HTTP request, using the template, passing the context
      return render(request, 'myapphere/index.html', context)

Creating the web page templates.

  • Create directory structure
    mkdir -p /home/django/myprojecthere/myapphere/templates/myapphere
  • Create new pages
    • templates/myapphere/index.html
    • templates/myapphere/stats.html

Example page content for the index.html page.

/home/django/myprojecthere/myapphere/templates/myapphere/index.html

<!DOCTYPE html>                                                                            
<html>
<head>
  <title>Asset List</title>
</head>
<body>
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'myapphere/style.css' %}" />
 
<!-- Export button jquery (https://github.com/kayalshri/tableExport.jquery.plugin) -->
<script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>
<script type="text/javascript" src="{% static 'myapphere/tableExport.js' %}"></script>
<script type="text/javascript" src="{% static 'myapphere/jquery.base64.js' %}"></script>
 
<!-- Layout Divide: Left Side Menu for Devices -->
<table class="layout">
<tr>
<!-- For white gaps in between Device Types and Phys/Virt, this must be larger than stylesheet width -->
<!-- Set to style sheet width+25 px -->
<td class="layout" width="696px">
 
<!-- Device Menu: Determine Active Device -->
<ul class="asset_type">
{% if not asset_type %}
  <li><a class="active" href="/myapphere/">All Devices</a></li>
{% else %}
  <li><a href="/myapphere/">All Devices</a></li>
{% endif %}
 
{% if asset_type == 'firewalls' %}
  <li><a class="active" href="/myapphere/firewalls/">Firewalls</a></li>
{% else %}
  <li><a href="/myapphere/firewalls/">Firewalls</a></li>
{% endif %}
 
{% if asset_type == 'routers' %}
  <li><a class="active" href="/myapphere/routers/">Routers</a></li>
{% else %}
  <li><a href="/myapphere/routers/">Routers</a></li>
{% endif %}
 
{% if asset_type == 'servers' %}
  <li><a class="active" href="/myapphere/servers/">Servers</a></li>
{% else %}
  <li><a href="/myapphere/servers/">Servers</a></li>
{% endif %}
 
{% if asset_type == 'storage' %}
  <li><a class="active" href="/myapphere/storage/">Storage</a></li>
{% else %}
  <li><a href="/myapphere/storage/">Storage</a></li>
{% endif %}
 
{% if asset_type == 'switches' %}
  <li><a class="active" href="/myapphere/switches/">Switches</a></li>
{% else %}
  <li><a href="/myapphere/switches/">Switches</a></li>
{% endif %}
 
{% if asset_type == 'workstations' %}
  <li><a class="active" href="/myapphere/workstations/">Workstations</a></li>
{% else %}
  <li><a href="/myapphere/workstations/">Workstations</a></li>
{% endif %}
 
</ul>
</td>
<!-- END of Layout Divide: Left Side Menu for Devices -->
 
 
<!-- Layout Divide: Right Side Phys and Virt Links -->
<!-- For white gaps in between Phys/Virt and Stats, this must be larger than stylesheet width -->
<!-- Set to style sheet width+25 px -->
<td class="layout" width="188px">
<!-- Asset Type Menu: Physical and Virtual -->
  <ul class ="asset_hardware">
  {% if asset_hardware == 'physical' %}
    <li><a class="active" href="/myapphere/physical/">Physical</a></li>
    <li><a href="/myapphere/virtual/">Virtual</a></li>
  {% elif asset_hardware == 'virtual' %}
    <li><a href="/myapphere/physical/">Physical</a></li>
    <li><a class="active" href="/myapphere/virtual/">Virtual</a></li>
  {% else %}
    <li><a href="/myapphere/physical/">Physical</a></li>
    <li><a href="/myapphere/virtual/">Virtual</a></li>
  {% endif %}
  </ul>
</td>
<!-- END of Layout Divide: Right Side Phys and Virt Links -->
 
 
<!-- Layout Divide: Right Side Additional Links -->
<td class="layout">
<ul class="stats">
  <li><a href="/myapphere/stats/">Stats</a></li>
</ul>
</td>
<!-- END of Layout Divide: Right Side Additional Links -->
 
</tr>
 
 
<!-- Layout Divide: Left Side Environment Menu -->
<tr>
<td class="layout">
 
<!-- Environment Menu: Dynamic Asset Type Links -->
<ul class="env">
{% if env == 'dev' %}
  {% if asset_type %}
    <li><a class="active" href="/myapphere/{{ asset_type }}/dev/">Dev</a></li>
    <li><a href="/myapphere/{{ asset_type }}/test/">Test</a></li>
    <li><a href="/myapphere/{{ asset_type }}/prod/">Prod</a></li>
  {% else %}
    <li><a class="active"href="/myapphere/dev/">Dev</a></li>
    <li><a href="/myapphere/test/">Test</a></li>
    <li><a href="/myapphere/prod/">Prod</a></li>
  {% endif %}
{% elif env == 'test' %}
  {% if asset_type %}
    <li><a href="/myapphere/{{ asset_type }}/dev/">Dev</a></li>
    <li><a class="active" href="/myapphere/{{ asset_type }}/test/">Test</a></li>
    <li><a href="/myapphere/{{ asset_type }}/prod/">Prod</a></li>
  {% else %}
    <li><a href="/myapphere/dev/">Dev</a></li>
    <li><a class="active" href="/myapphere/test/">Test</a></li>
    <li><a href="/myapphere/prod/">Prod</a></li>
  {% endif %}
{% elif env == 'prod' %}
  {% if asset_type %}
    <li><a href="/myapphere/{{ asset_type }}/dev/">Dev</a></li>
    <li><a href="/myapphere/{{ asset_type }}/test/">Test</a></li>
    <li><a class="active" href="/myapphere/{{ asset_type }}/prod/">Prod</a></li>
  {% else %}
    <li><a href="/myapphere/dev/">Dev</a></li>
    <li><a href="/myapphere/test/">Test</a></li>
    <li><a class="active" href="/myapphere/prod/">Prod</a></li>
  {% endif %}
{% else %}
  {% if asset_type %}
    <li><a href="/myapphere/{{ asset_type }}/dev/">Dev</a></li>
    <li><a href="/myapphere/{{ asset_type }}/test/">Test</a></li>
    <li><a href="/myapphere/{{ asset_type }}/prod/">Prod</a></li>
  {% else %}
    <li><a href="/myapphere/dev/">Dev</a></li>
    <li><a href="/myapphere/test/">Test</a></li>
    <li><a href="/myapphere/prod/">Prod</a></li>
  {% endif %}
{% endif %}
</ul>
</td>
<!-- END of Layout Divide: Left Side Environment Menu -->
 
 
<!-- START of Layout Divide: 2nd row for logged in message -->
<td class="layout">
{% if user.is_authenticated %}
  Logged in: {{ user.username }}<br>
  <a class="plain" href="/logout/">Logout</a>
{% endif %}
</td> 
</tr>
<!-- END of Layout Divide: 2nd row for logged in message -->
 
 
<!-- Layout Divide: Bottom Asset List Table -->
<tr>
<td class="layout" colspan=3>
 
<!-- Asset List Above Table: Display Device and Environment -->
<br>
{% if asset_type == 'firewalls' %}
  {% if env == 'dev' %}
  <b>Asset List - Firewalls - Development Environment</b>
  {% elif env == 'test' %}
  <b>Asset List - Firewalls - Test Environment</b>
  {% elif env == 'prod' %}
  <b>Asset List - Firewalls - Production Environment</b>
  {% else %}
  <b>Asset List - Firewalls - All Environments</b>
  {% endif %}
 
{% elif asset_type == 'routers' %}
  {% if env == 'dev' %}
  <b>Asset List - Routers - Development Environment</b>
  {% elif env == 'test' %}
  <b>Asset List - Routers - Test Environment</b>
  {% elif env == 'prod' %}
  <b>Asset List - Routers - Production Environment</b>
  {% else %}
  <b>Asset List - Routers - All Environments</b>
  {% endif %}
 
{% elif asset_type == 'servers' %}
  {% if env == 'dev' %}
  <b>Asset List - Servers - Development Environment</b>
  {% elif env == 'test' %}
  <b>Asset List - Servers - Test Environment</b>
  {% elif env == 'prod' %}
  <b>Asset List - Servers - Production Environment</b>
  {% else %}
  <b>Asset List - Servers - All Environments</b>
  {% endif %}
 
{% elif asset_type == 'storage' %}
  {% if env == 'dev' %}
  <b>Asset List - Storage - Development Environment</b>
  {% elif env == 'test' %}
  <b>Asset List - Storage - Test Environment</b>
  {% elif env == 'prod' %}
  <b>Asset List - Storage - Production Environment</b>
  {% else %}
  <b>Asset List - Storage - All Environments</b>
  {% endif %}
 
{% elif asset_type == 'switches' %}
  {% if env == 'dev' %}
  <b>Asset List - Switches - Development Environment</b>
  {% elif env == 'test' %}
  <b>Asset List - Switches - Test Environment</b>
  {% elif env == 'prod' %}
  <b>Asset List - Switches - Production Environment</b>
  {% else %}
  <b>Asset List - Switches - All Environments</b>
  {% endif %}
 
{% elif asset_type == 'workstations' %}
  {% if env == 'dev' %}
  <b>Asset List - Workstations - Development Environment</b>
  {% elif env == 'test' %}
  <b>Asset List - Workstations - Test Environment</b>
  {% elif env == 'prod' %}
  <b>Asset List - Workstations - Production Environment</b>
  {% else %}
  <b>Asset List - Workstations - All Environments</b>
  {% endif %}
 
{% else %}
  {% if env == 'dev' %}
  <b>Asset List - All Types - Development Environment</b>
  {% elif env == 'test' %}
  <b>Asset List - All Types - Test Environment</b>
  {% elif env == 'prod' %}
  <b>Asset List - All Types - Production Environment</b>
  {% else %}
  <b>Asset List - All Types - All Environments</b>
  {% endif %}
{% endif %}
 
<!-- Physical/Virtual Filter -->
{% if asset_hardware %}
  {% if asset_hardware == 'physical' %}
    <b> - Physical -</b>
  {% elif asset_hardware == 'virtual' %}
    <b> - Virtual -</b>
  {% endif %}
{% endif %}
 
<!-- Assets List Above Table: Number of Assets Displayed -->
{% if asset_count %}
  {% if asset_count == 1 %}
    <b> ({{ asset_count }} asset)</b>
  {% else %}
    <b> ({{ asset_count }} assets)</b>
  {% endif %}
{% else %}
  <b> (0 assets)</b>
{% endif %}
 
<!-- Export Buttons -->
<a href="#" class="plain" onclick="$('#assetlist').tableExport({type:'csv',escape:'false'});"><img src="{% static 'myapphere/csv.png' %}" width="24px" title="Export CSV"></a>
<a href="#" class="plain" onclick="$('#assetlist').tableExport({type:'excel',escape:'false'});"><img src="{% static 'myapphere/xls.png' %}" width="24px" title="Export Excel"></a>
 
<br>
<!-- The Assets List Table -->
<table class="myapphere" id="assetlist">
 <thead>
  <tr class="myapphere">
    <th class="myapphere">Device</th>
    <th class="myapphere">Name</th>
    <th class="myapphere">Description</th>
    <th class="myapphere">Environment</th>
    <th class="myapphere">OS</th>
    <th class="myapphere">Type</th>
  </tr>
 </thead>
 <tbody
  {% for name in all_asset_list %}
    <tr class="myapphere">
      <td class="myapphere">{{ name.asset_type }}</td>
      <td class="myapphere">{{ name.asset_name }}</td>
      <td class="myapphere">{{ name.asset_description }}</td>
      <td class="myapphere center">{{ name.asset_env }}</td>
      <td class="myapphere center">{{ name.asset_os }}</td>
      <td class="myapphere center">{{ name.asset_hardware }}</td>
    </tr>
  {% endfor %}
 </tbody>
</table>
<!-- END of Assets List Table -->
 
</td>
</tr>
</table>
<!-- END of Layout Divide: Bottom Assets List Table -->
 
<br>
<hr>
<br>
 
</body>
</html>

Example page content for the stats.html page.

/home/django/myprojecthere/myapphere/templates/myapphere/stats.html

<!DOCTYPE html>                                                                            
<html>
<head>
  <title>Asset List - Stats</title>
</head>
<body>
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'myapphere/style.css' %}" />
 
<!-- Export button jquery (https://github.com/kayalshri/tableExport.jquery.plugin) -->
<script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>
<script type="text/javascript" src="{% static 'myapphere/tableExport.js' %}"></script>
<script type="text/javascript" src="{% static 'myapphere/jquery.base64.js' %}"></script>
 
<!-- Layout Divide: Left Side Menu for Devices -->
<table class="layout">
<tr>
<!-- For white gaps in between Device Types and Phys/Virt, this must be larger than stylesheet width -->
<!-- Set to style sheet width+25 px -->
<td class="layout" width="696px">
 
<!-- Device Menu: No Devices Active on Stats Page -->
<ul class="asset_type">
<li><a href="/myapphere/">All Devices</a></li>
<li><a href="/myapphere/firewalls/">Firewalls</a></li>
<li><a href="/myapphere/routers/">Routers</a></li>
<li><a href="/myapphere/servers/">Servers</a></li>
<li><a href="/myapphere/storage/">Storage</a></li>
<li><a href="/myapphere/switches/">Switches</a></li>
<li><a href="/myapphere/workstations/">Workstations</a></li>
</ul>
</td>
<!-- END of Layout Divide: Left Side Menu for Devices -->
 
 
<!-- Layout Divide: Right Side Phys and Virt Links -->
<!-- For white gaps in between Phys/Virt and Stats, this must be larger than stylesheet width -->
<!-- Set to style sheet width+25 px -->
<td class="layout" width="188px">
<!-- Asset Type Menu: Physical and Virtual -->
  <ul class ="asset_hardware">
  {% if asset_hardware == 'physical' %}
    <li><a class="active" href="/myapphere/physical/">Physical</a></li>
    <li><a href="/myapphere/virtual/">Virtual</a></li>
  {% elif asset_hardware == 'virtual' %}
    <li><a href="/myapphere/physical/">Physical</a></li>
    <li><a class="active" href="/myapphere/virtual/">Virtual</a></li>
  {% else %}
    <li><a href="/myapphere/physical/">Physical</a></li>
    <li><a href="/myapphere/virtual/">Virtual</a></li>
  {% endif %}
  </ul>
</td>
<!-- END of Layout Divide: Right Side Phys and Virt Links -->
 
 
<!-- Layout Divide: Right Side Additional Links -->
<td class="layout">
<ul class="stats">
  <li><a class="active" href="/myapphere/stats/">Stats</a></li>
</ul>
</td>
<!-- END of Layout Divide: Right Side Additional Links -->
 
</tr>
 
 
<!-- START of Layout Divide: 2nd row for logged in message -->
<tr>
<td class="layout">
</td>
 
<td class="layout">
{% if user.is_authenticated %}
  Logged in: {{ user.username }}<br>
  <a class="plain" href="/logout/">Logout</a>                                              
{% endif %}
</td>
</tr>
<!-- END of Layout Divide: 2nd row for logged in message -->
 
 
<!-- Layout Divide: Bottom Stats Table (Asset Counts) -->
<tr>
<td class="layout" colspan=3>
 
<br>
<b>Asset List - Statistics - Asset Counts</b>
 
<!-- Export Buttons -->
<a href="#" class="plain" onclick="$('#assetcounts').tableExport({type:'csv',escape:'false'});"><img src="{% static 'myapphere/csv.png' %}" width="24px" title="Export CSV"></a>
<a href="#" class="plain" onclick="$('#assetcounts').tableExport({type:'excel',escape:'false'});"><img src="{% static 'myapphere/xls.png' %}" width="24px" title="Export Excel"></a>
 
<br>
<!-- Stats Table (Asset Counts) -->
<table class="myapphere" id="assetcounts">
<thead>
  <tr class="myapphere">
    <th class="myapphere">Device Type</th>
    <th class="myapphere">Systems</th>
    <th class="myapphere">Physical</th>
    <th class="myapphere">Physical Linux</th>
    <th class="myapphere">Physical Windows</th>
    <th class="myapphere">Physical Other</th>
    <th class="myapphere">Virtual</th>
    <th class="myapphere">Virtual Linux</th>
    <th class="myapphere">Virtual Windows</th>
    <th class="myapphere">Virtual Other</th>
  </tr>
</thead>
<tbody>
  {% for asset in device_stats %}
    <tr class="myapphere">
      {% if asset.asset_type == 'Total' %}
        <td class="myapphere totals"><b>{{ asset.asset_type }}</b></td>
        <td class="myapphere center totals">{{ asset.total }}</td>
        <td class="myapphere center totals">{{ asset.physical }}</td>
        <td class="myapphere center totals">{{ asset.physical_linux }}</td>
        <td class="myapphere center totals">{{ asset.physical_windows }}</td>
        <td class="myapphere center totals">{{ asset.physical_other }}</td>
        <td class="myapphere center totals">{{ asset.virtual }}</td>
        <td class="myapphere center totals">{{ asset.virtual_linux }}</td>
        <td class="myapphere center totals">{{ asset.virtual_windows }}</td>
        <td class="myapphere center totals">{{ asset.virtual_other }}</td>
      {% else %}
        <td class="myapphere">{{ asset.asset_type }}</td>
        <td class="myapphere center">{{ asset.total }}</td>
        <td class="myapphere center">{{ asset.physical }}</td>
        <td class="myapphere center">{{ asset.physical_linux }}</td>
        <td class="myapphere center">{{ asset.physical_windows }}</td>
        <td class="myapphere center">{{ asset.physical_other }}</td>
        <td class="myapphere center">{{ asset.virtual }}</td>
        <td class="myapphere center">{{ asset.virtual_linux }}</td>
        <td class="myapphere center">{{ asset.virtual_windows }}</td>
        <td class="myapphere center">{{ asset.virtual_other }}</td>
      {% endif %}
    </tr>
  {% endfor %}
  <tr class="myapphere">
    <td class="myapphere totals">Total Linux</td>
    <td class="myapphere center">{{ total_linux }}</td>
  </tr>
  <tr class="myapphere">
    <td class="myapphere totals">Total Windows</td>
    <td class="myapphere center">{{ total_windows }}</td>
  </tr>
  <tr class="myapphere">
    <td class="myapphere totals">Total Other</td>                                          
    <td class="myapphere center">{{ total_other }}</td>
  </tr>
  <tr class="myapphere">
    <td class="myapphere totals">Total VMware ESXi*</td>
    <td class="myapphere center">{{ total_vmware }}</td>
  </tr>
</tbody>
</table>
*Physical Virtual Hosts (VMware ESXi) count is included in Physical Linux/Total Linux counts.
<!-- END of Stats Table (Asset Counts) -->
 
</td>
</tr>
<!-- END of Layout Divide: Bottom Stats Table (Asset Counts) -->
 
<!-- Layout Divide: Bottom Stats Table (OS Counts) -->
<tr>
<td class="layout" colspan=3>
 
<br>
<b>Asset List - Statistics - OS Counts</b>
 
<!-- Export Buttons -->
<a href="#" class="plain" onclick="$('#oscounts').tableExport({type:'csv',escape:'false'});"><img src="{% static 'myapphere/csv.png' %}" width="24px" title="Export CSV"></a>
<a href="#" class="plain" onclick="$('#oscounts').tableExport({type:'excel',escape:'false'});"><img src="{% static 'myapphere/xls.png' %}" width="24px" title="Export Excel"></a>
 
<br>
<!-- Stats Table (OS Counts) -->
<table class="myapphere" id="oscounts">
<thead>
  <tr class="myapphere">
    <th class="myapphere">Device Type</th>
    {% for os_name in os_list %}
      <th class="myapphere">{{ os_name }}</th>
    {% endfor %}
  </tr>
</thead>
<tbody>
  {% for asset in device_stats %}
    <tr class="myapphere">
      {% if asset.asset_type == 'Total' %}
        <td class="myapphere totals"><b>{{ asset.asset_type }}</b></td>
        {% for name in asset.os_count_stats %}
          <td class="myapphere center totals">{{ name.count }}</td>
        {% endfor %}
 
      {% else %}
        <td class="myapphere">{{ asset.asset_type }}</td>
        {% for name in asset.os_count_stats %}
          <td class="myapphere center">{{ name.count }}</td>
        {% endfor %}
      {% endif %}
    </tr>
 
  {% endfor %}
</tbody>
</table>
<!-- END of Stats Table (OS Counts) -->
 
</td>
</tr>
</table>
<!-- END of Layout Divide: Bottom Stats Table (OS Counts) -->
 
<br>
<hr>
<br>
 
</body>
</html>

Configuring stylesheets.

  • Create directory structure
    mkdir -p /home/django/myprojecthere/myapphere/static/myapphere
  • Create stylesheet (/home/django/myprojecthere/myapphere/static/myapphere/style.css)
    /* style.css : Styles for html templates */                                                
     
    /* ---- Table Styles ---- */
    /* table settings */
    table.layout {
      border-collapse: collapse;
      border-spacing: 0px;
      padding: 0px;
    }
    td.layout {
      border-spacing: 0px;
      padding: 0px;
    }
     
    table.myapphere {
      border-collapse: collapse;
    }
     
    /* table headers, table definitions */
    table.myapphere, th.myapphere, td.myapphere {
      border-collapse: collapse;
      border: 1px solid #ddd;
      padding: 5px;
    }
     
    /* th -> table headers */
    th.myapphere {
        background-color: #4CAF50;
        color: white;
    }
     
    /* tr -> table rows
     *  * tr:nth-child -> color every even table row 
     *   * tr:hover -> Mouse hover background color effect */
    tr.myapphere:nth-child(even) {background-color: #f2f2f2;}
    tr.myapphere:hover {background-color: #ddd;}
     
    td.center {
      text-align: center;
    }
     
    td.totals {
      background-color: #b3b3b3;
      font-weight: bold;
    }
     
     
    /* ---- Menu Styles ---- */
    ul.asset_type {
      list-style-type: none;
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #333;
      width: 671px;
    }
     
    ul.env {
      list-style-type: none;
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #333;
      width: 163px;
    }
     
    ul.stats {
      list-style-type: none;
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #333;
      width: 60px;
    }
     
    ul.asset_hardware {
      list-style-type: none;
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #333;
      width: 163px;
    }
     
    li {
      float: left;
    }
     
    li a {
      display: block;
      color: white;
      text-align: center;
      padding: 10px 10px;
      text-decoration: none;
    }
     
    a:hover:not(.active) {
      background-color: #111;
    }
     
    .active {
      background-color:#4CAF50;
    }
     
     
    /* ---- Non-Menu Styles ---- */
    a:link.plain {
      background-color: #ffffff;
    }
    a:visited.plain {
      background-color: #ffffff;
    }
     
    a:hover.plain {
      background-color: #4caf50;
    }

Apache

Configuring Apache to pass traffic to the application.

  • Configure Apache's mod_wsgi for the application (new file)
    vim /etc/httpd/conf.d/myapphere.conf
     
    # Asset List Django/WSGI Config
     
    # WSGIScriptAlias: The base URL to serve the application from
    WSGIScriptAlias / /home/django/myprojecthere/myprojecthere/wsgi.py
     
    # WSGI Daemon Process Config
    WSGIDaemonProcess myapphere python-path=/home/django/myprojecthere
    WSGIProcessGroup myapphere
     
    # Location of Django Application and wsgi.py config
    <Directory /home/django/myprojecthere/myprojecthere>
      <Files wsgi.py>
        Require all granted
      </Files>
    </Directory>
     
    # Static files (admin interface and style sheet)
    Alias /static/ /var/www/static/
    <Directory /var/www/static/>
      Require all granted
    </Directory>
  • Configure the virtual host (new file)
    vim /etc/httpd/conf.d/vhosts.conf
     
    # Virtual Host Config
     
    # Redirect shortname to fully qualified
    <VirtualHost *:80>
      ServerName djangoserver
      Redirect "/" "http://djangoserver.mycorps.domain.org/"
    </VirtualHost>
     
    # Redirect all http to https
    <VirtualHost *:80>
      ServerName djangoserver.mycorps.domain.org
     
      <IfModule mod_rewrite.c>
        # Redirect all to https
        RewriteEngine On
        RewriteCond %{HTTPS} off
        RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
      </IfModule>
    </VirtualHost>
     
     
    # Redirect shortname to fully qualified
    <VirtualHost *:443>
      ServerName djangoserver
      Redirect "/" "https://djangoserver.mycorps.domain.org/"
    </VirtualHost>
     
    # Django Application lives here at the root /. See: /etc/httpd/conf.d/myapphere.conf
    <VirtualHost *:443>
      # Fully qualified server name
      ServerName djangoserver.mycorps.domain.org
      Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"
    </VirtualHost>
     
    <VirtualHost *:443>
      # OPTIONAL: CNAME for website - will only work with SSL if using a wildcard certificate
      ServerName myapphere.mycorps.domain.org
      Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains;"
    </VirtualHost>
  • Configure SSL Certificate
    vim /etc/httpd/conf.d/ssl.conf
     
    SSLCertificateFile /etc/pki/tls/certs/current_crt.crt
    SSLCertificateKeyFile /etc/pki/tls/certs/current_key.key
    SSLCertificateChainFile /etc/pki/tls/certs/current_ca.crt
  • Start and Enable Apache
    systemctl start httpd
    systemctl enable httpd

Django: Authentication

Adding authentication to Django requires basic auth to be setup first, as LDAP auth builds upon it.

Basic authentication uses Django local user accounts.

  • Edit Project Settings (/home/django/myprojecthere/myprojecthere/settings.py)
    # Redirect Successful Logins Here
    LOGIN_REDIRECT_URL = '/myapphere/'
     
    # Ensure contrib.auth is added to installed apps:
    # Application definition
    INSTALLED_APPS = [
        'myapphere.apps.MyapphereConfig',
        'django.contrib.admin',
        'django.contrib.auth',    # must exist for basic auth to work
    ...
    ]
  • Add login and logout URLs to project URLs (/home/django/myprojecthere/myprojecthere/urls.py)
    # auth views - authentication login/logout module
    from django.contrib.auth import views as auth_views
     
    # URL Patterns - Map to Projects Within Django
    urlpatterns = [
        ...
        # Login URLs
        url(r'^login/$', auth_views.login, {'template_name': 'login.html'}, name='login'),
        url(r'^logout/$', auth_views.logout, {'next_page': '/login/'}, name='logout'),
        ...
    ]
  • Edit the application views (/home/django/myprojecthere/myapphere/views.py)
    # Require login decorator
    from django.contrib.auth.decorators import login_required
     
    # Put login decorator before every function definition that you want to require login to view:
    #-> Require login for the view following it <-#
    @login_required(login_url="/login/")
     
    def index(request):
  • Create a HTML Login Page (/home/django/myprojecthere/myapphere/templates/login.html)
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>{% block title %}Asset List{% endblock %}</title>
    </head>
     
    <body>
      <header>
        <h1>Asset List</h1>
        {% if user.is_authenticated %}
          Greetings, {{ user.username }}.
          <a href="{% url 'logout' %}">logout</a>
        {% endif %}
      </header>
     
      <hr>
      <main>
      <h2>Login</h2>
      <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Login</button>
      </form>
      </main>
      <hr>
     
    </body>
    </html>

Configuring LDAP authentication.

  • Install the python django ldap package
    pip install django-auth-ldap
  • Edit Project Settings (/home/django/myprojecthere/myprojecthere/settings.py)
     # LDAP Module Imports
    import ldap
    from django_auth_ldap.config import LDAPSearch
    from django_auth_ldap.config import GroupOfNamesType
    from django_auth_ldap.config import LDAPGroupQuery
     
    # Authentication Backends (LDAP and Django Local)
    AUTHENTICATION_BACKENDS = (
        'django_auth_ldap.backend.LDAPBackend',
        'django.contrib.auth.backends.ModelBackend',
    )
     
    ####- LDAP Server Config -####
    AUTH_LDAP_SERVER_URI = "ldap://LDAPSERVER01.mycorps.domain.org ldap://LDAPSERVER02.mycorps.domain.org"
    AUTH_LDAP_START_TLS = True
     
    # Bind Info: Use authenticating user to get user and group info
    AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True
    AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,cn=users,cn=accounts,dc=mycorps,dc=domain,dc=org"
     
    # Cache LDAP Groups for use with permissions
    AUTH_LDAP_CACHE_GROUPS = True
    AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600
     
    # Group Info Gathering
    AUTH_LDAP_GROUP_SEARCH = LDAPSearch
      "cn=groups,cn=accounts,dc=mycorps,dc=domain,dc=org",
      ldap.SCOPE_SUBTREE,
      "(objectClass=groupofnames)"
    )
    AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
     
    # Group restrictions - Who can login via LDAP
    AUTH_LDAP_REQUIRE_GROUP = (
     
      # Allow login for members of the LDAP group "list_users"
      LDAPGroupQuery("cn=list_users,cn=groups,cn=accounts,dc=mycorps,dc=domain,dc=org") |
     
      # Allow login for members of the LDAP group "admin_group"
      LDAPGroupQuery("cn=admin_group,cn=groups,cn=accounts,dc=mycorps,dc=domain,dc=org")
    )
     
    # Use LDAP group membership to calculate group permissions.
    AUTH_LDAP_FIND_GROUP_PERMS = True
     
    # Update Django record from LDAP each time user logs in
    AUTH_LDAP_ALWAYS_UPDATE_USER = True
     
    # Populate the Django user info from LDAP directory info
    AUTH_LDAP_USER_ATTR_MAP = {
        "first_name": "givenname",
        "last_name": "sn",
        "email": "mail"
    }
     
    # Set user permission flags by group - set LDAP group "admin_group" as Django Staff Members
    AUTH_LDAP_USER_FLAGS_BY_GROUP = {
        "is_staff": "cn=admin_group,cn=groups,cn=accounts,dc=mycorps,dc=domain,dc=org"
    }

Django: Jquery

Jquery can be added in order to enable an Export as CSV and/or Excel buttons.

Reference: Export Jquery Buttons: https://github.com/kayalshri/tableExport.jquery.plugin

  • From the reference link, download:
    • jquery.base64.js
    • tableExport.js
  • Search the internet for CSV and XLS icons. Download them.
    • CSV = save as “csv.png”
    • XLS = save as “xls.png”
  • Save the Javascript files and small pictures (CSV/XLS) into the same directory as the style sheet
    /home/django/myprojecthere/myapphere/static/myapphere/
  • Install the Django Jquery integration
    pip install django-jquery
  • Add Jquery to the “INSTALLED_APPS” list (/home/django/myprojecthere/myprojecthere/settings.py)
    # Application definition
    INSTALLED_APPS = [
        'jquery',
  • Add jquery to HTML templates
    <!-- Export button jquery support (https://github.com/kayalshri/tableExport.jquery.plugin) -->
    <script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>
    <script type="text/javascript" src="{% static 'myapphere/tableExport.js' %}"></script>
    <script type="text/javascript" src="{% static 'myapphere/jquery.base64.js' %}"></script>
     
    <!-- Export Buttons -->
    <a href="#" class="plain" onclick="$('#assetlist').tableExport({type:'csv',escape:'false'});"><img src="{% static 'myapphere/csv.png' %}" width="24px" title="Export CSV"></a>
    <a href="#" class="plain" onclick="$('#assetlist').tableExport({type:'excel',escape:'false'});"><img src="{% static 'myapphere/xls.png' %}" width="24px" title="Export Excel"></a>
  • Collect static files
    cd /home/django/myprojecthere/
    python manage.py collectstatic

  • python_wiki/django_configuration.1533328042.txt.gz
  • Last modified: 2019/05/25 23:50
  • (external edit)