Django

From Network Security Wiki


Source: djangoproject.com

Installing

Installation:

sudo pip3 install django

Check installed version:

python3 -m django --version

Creating project

mkdir ~/mycode
cd  ~/mycode                  #Do not put code under /var/www
django-admin startproject mysite 

Avoid using names like

django: conflict with Django itself
test:   conflicts with a built-in Python package

Startproject command will create:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py


These files are:

  • The outer mysite/: Just a container for the project. It can be renamed it to anything.
  • manage.py: Command-line utility that allows to interact with this Django project in various ways.
  • The inner mysite/ directory is the actual Python package for the project. This is the Python package name to use to import anything inside it (e.g. mysite.urls).
  • mysite/__init__.py: Empty file that tells Python that this directory should be considered a Python package.
  • mysite/settings.py: Settings/configuration for this Django project.
  • mysite/urls.py: The URL declarations for this Django project; a “table of contents” of your Django-powered site.
  • mysite/wsgi.py: An entry-point for WSGI-compatible web servers to serve your project.

Running Project

cd ~/mycode/mysite/
python3 manage.py runserver
http://127.0.0.1:8000/

Changing the port

python3 manage.py runserver 8080

Listen on all available public IPs:

python3 manage.py runserver 0:8000
python3 manage.py runserver 0.0.0.0:8000

Automatic reloading of runserver:

The server automatically reloads Python code for each request as needed.
No need to restart the server for code changes to take effect. 
Some actions like adding files don’t trigger a restart, need to restart the server in these cases.

Invalid http_host Header error:

Need to add 198.211.99.20 to ALLOWED_HOSTS setting in project settings.py file
cd ~/mycode/mysite/mysite
nano settings.py
ALLOWED_HOSTS = ['198.211.99.20', 'localhost', '127.0.0.1']

Creating an App

 cd mytool
 python3 manage.py startapp myapp
  • This is the simplest view possible in Django.
  • Edit the /mytool/myapp/views.py file:
 from django.http import HttpResponse

 def index(request):
   return HttpResponse("Hello world!")
  • To call the view, we need to map it to a URL - and for this we need a URLconf.
  • To create a URLconf in the polls directory, create a file called urls.py.
  • Create the /mytool/myapp/urls.py file:
 from django.conf.urls import url

 from . import views

 urlpatterns = [
   url(r'^$', views.index, name='index'),
 ]
  • The next step is to point the root URLconf at the myapp.urls module.
  • In mytool/urls.py, add an import for django.urls.include and insert an include() in the urlpatterns list,
  • Edit the /mytool/mytool/urls.py file and modify it to look like this:
 from django.conf.urls import url
 from django.urls import include

 urlpatterns = [
     url(r'^myapp/', include('myapp.urls')),
 ]

Test the site:

http://10.140.197.8:8080/myapp/

Understanding Parameters

  • The path() function is passed four arguments,
two required: route and view
two optional: kwargs, and name. 
  • Route:
Route is a string that contains a URL pattern. 
When processing a request, Django starts at the first pattern in urlpatterns and makes its way down the list, comparing the requested URL against each pattern until it finds one that matches.
Patterns don’t search GET and POST parameters, or the domain name. 
For example, in a request to https://www.example.com/myapp/, the URLconf will look for myapp/. 
In a request to https://www.example.com/myapp/?page=3, the URLconf will also look for myapp/.
  • View:
When Django finds a matching pattern, it calls the specified view function with an HttpRequest object as the first argument and any “captured” values from the route as keyword arguments.
  • Kwargs:
Arbitrary keyword arguments can be passed in a dictionary to the target view. 
  • Name:
Naming your URL lets you refer to it unambiguously from elsewhere in Django, especially from within templates. 
This powerful feature allows you to make global changes to the URL patterns of your project while only touching a single file.

Using Database

        This section is under construction.

HTML Response

  • Edit the views.py file:
nano /myproject/myapp/views.py
from django.http import HttpResponse
from django.template import engines
from myapp.models import user

def add(request):
    title = 'Index Page'
    author = 'Amandeep Singh'

    about_template = '''<!DOCTYPE html>
    <html>
    <head>
       <title>{{ title }}</title>
    </head>
    <body>
      <h1>Add a User</h1>
      <p> <a href="{% url 'home' %}">Home</a> </p>
    </body>
    </html>
    '''

    django_engine = engines['django']
    template = django_engine.from_string(about_template)
    html = template.render({'title': title, 'author': author})
    return HttpResponse(html)
  • Create the models.py file:
nano /myproject/myapp/models.py
                                                                              
from django.db import models

class user(models.Model):
    name = models.CharField(max_length = 100)
    city = models.CharField(max_length = 100, default = 'Kapurthala')

    def __str__(self):
        return self.name
  • Edit the views.py file:
nano /myproject/myapp/views.py
from django.shortcuts import render
from myapp.models import user

def add(request):
    title = 'Index Page'
    author = 'Amandeep Singh'

    about_template = '''<!DOCTYPE html>
    <html>
    <head>
       <title>{{ title }}</title>
    </head>
    <body>
      <h1>Add a User</h1>
      <p> <a href="{% url 'home' %}">Home</a> </p>
    </body>
    </html>
    '''

    django_engine = engines['django']
    template = django_engine.from_string(about_template)
    html = template.render({'title': title, 'author': author})
    return HttpResponse(html)
  • Edit the urls.py file:
nano /myproject/myapp/urls.py
                                                                              
from myapp.views import home

urlpatterns=[
    url(r'^admin/', admin.site.urls),
    url(r'^add/', home, name = 'add'),
]

Rendering Data from Database (Model)

Source: stackoverflow.com

  • Create a Template file:
nano myproject/myapp/templates/home.html
<!DOCTYPE html>
<html>
    <head>
       <title>{{ title }}</title>
    </head>
    <body>
      <h1>Reminder App</h1>
      <table>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>City</th>
        </tr>
        {% if user_list %}
           There are {{ user_list|length }} records:
           {% for item in user_list %}
            <tr>
             <td>{{ item.id }}</td>
             <td>{{ item.name }}</td>
             <td>{{ item.city }}</td>
            </tr>
           {% endfor %}

      </table>
    </body>
</html>
  • Edit the views file:
nano /myproject/myapp/views.py
from django.shortcuts import render
from myapp.models import user

def home(request):
    users_list = user.objects.all()
    #print(user_list[0].phone)
    return render(request,'home.html',{'user_list':users_list})
  • Create the Models file:
nano /myproject/myapp/models.py
                                                                              
from django.db import models

class user(models.Model):
    name = models.CharField(max_length = 100)
    city = models.CharField(max_length = 100, default = 'Kapurthala')

    def __str__(self):
        return self.name
  • Edit the urls.py file:
nano /myproject/myapp/urls.py
                                                                              
from myapp.views import home

urlpatterns=[
    url(r'^admin/', admin.site.urls),
    url(r'^home/', home, name = 'home'),
]

Save Data to Database (Model)

  • Create a file forms.py
nano myapp/myapp/forms.py
from django import forms
from myapp.models import user

class userForm(forms.ModelForm):
    class Meta:
        model = user
        fields = "__all__"


  • Edit the urls.py file:
nano  myapp/myapp/urls.py
from myapp.views import home,add,delete,backup,test,success

urlpatterns=[
    url(r'^admin/', admin.site.urls),
    url(r'^home/', home, name = 'home'),
    url(r'^add/', add, name = 'add'),
    url(r'^delete/', delete, name = 'delete'),
    url(r'^backup/', backup, name = 'backup'),
    url(r'^test/', test, name = 'test'),
    url(r'^success/', success, name = 'success'),

]
  • Models file models.py remains the same
  • Create a new Template file:
nano  myapp/myapp/templates/add.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Add User</title>
        {% load static %}
    </head>
    <body>
    <form method="POST" action="add/">
            {% csrf_token %}
        <br>
        <h3>Enter Details</h3>
        <br>
      <!---    {{ form.as_p }}  --->
      <!---    {{ form }}       --->
          <label>Name:</label>
          {{ form.name }}
          <br>
          <label>City:</label>
          {{ form.city }}
          <br>
        <button type="submit">Submit</button>
    </form>
</body>
</html>
  • Edit the views.py file
nano .myapp/myapp/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.template import engines
from django.shortcuts import render
from myapp.forms import userForm
from myapp.models import user


def home(request):
    users_list = user.objects.all()
    #print(user_list[0].phone)
    return render(request,'home.html',{'user_list':users_list})

def add(request):
    if request.method == "POST":
        form = userForm(request.POST)
        if form.is_valid():
            try:
                form.save()
                #return redirect('success')
                return HttpResponseRedirect('/success')
            except:
                pass
    else:
        form = userForm()
    return render(request,'add.html',{'form':form})

def success(request):
    about_template = '''<!DOCTYPE html>
    <html>
    <head>
       <title>{{ title }}</title>
    </head>
    <body>
        <p> User successfully added </p>
        <p> <a href="{% url 'home' %}">Home</a> </p>
    </body>
    </html>
    '''
    django_engine = engines['django']
    template = django_engine.from_string(about_template)
    html = template.render()
    return HttpResponse(html)

Delete Entry

Edit the urls.py file:

nano myapp/myapp/urls.py
from myapp.views import destroy

urlpatterns=[
    url(r'^delete/(?P<id>[\d]+)/$', destroy, name='destroy'),
]

Edit the views.py file:

nano myapp/myapp/views.py
from django.shortcuts import redirect

def destroy(request,id):
    user_list = user.objects.get(id=id)
    user_list.delete()
    return redirect("/home")

Edit the home.html Template file:

nano myapp/myapp/templates/home.html
<th>Actions</th>

<a href="/delete/{{ item.id }}">Delete</a>

Edit Entry

  • Edit the urls.py file:
nano myapp/myapp/urls.py
from myapp.views import edit,update

urlpatterns=[
    url(r'^edit/(?P<id>[\d]+)/$', edit, name = 'edit'),
    url(r'^update/(?P<id>[\d]+)/$', update, name = 'update'),
]
  • Edit the views.py file:
nano myapp/myapp/views.py
from django.http import HttpResponse
from django.shortcuts import render, redirect
from myapp.forms import userForm
from myapp.models import user

def edit(request, id):
    user_list = user.objects.get(id=id)
    return render(request,'edit.html', {'user':user_list})

def update(request, id):
    user_list = user.objects.get(id=id)
    form = userForm(request.POST, instance = user_list)
    if form.is_valid():
        try:
            form.save()
            return redirect("home")
        except:
            pass
    return render(request, 'edit.html', {'user': user_list})
  • Edit the home.html Template file:
nano myapp/myapp/templates/edit.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Index</title>
    {% load static %}
  </head>
  <body>
    <form method="POST" action="/update/{{ user.id }}/">
      {% csrf_token %}
        <center>
        <h3>Update Details</h3>
        <label >Name:</label><input name="name" value="{{ user.name }}" /><br>
        <label >City:</label><input name="city" value="{{ user.city }}" /><br>
        <label >Phone:</label><input name="phone" value="{{ user.phone }}" /><br>
        <button type="submit">Update</button>
        </center>
    </form>
  </body>
</html>

Make an entry Unique

  • Edit the views.py file:
nano myapp/myapp/views.py
from django.db import utils

def update(request, id):
    user_list = user.objects.get(id=id)
    form = userForm(request.POST, instance = user_list)
    if form.is_valid():
        try:
            form.save()
            return redirect("/home")
            #return HttpResponseRedirect('/success')
        except Exception as e:
            return HttpResponse("Exception: "+ str(e))
    else:
        return HttpResponse("Invalid Data:" + str(form.errors.as_data()))
        #return HttpResponse("Invalid Data")
    return render(request, 'edit.html', {'user': user_list})
  • Edit the models.py file & make Phone no Unique:
nano myapp/myapp/models.py
class user(models.Model):
    name = models.CharField(max_length = 40)
    city = models.CharField(max_length = 40, default = 'Kapurthala')
    phone = models.CharField(max_length = 14, unique = True)

    def __str__(self):
        return self.name

Run a Script

  • Edit the urls.py file:
nano myapp/myapp/urls.py
from myapp.views import sendsms

urlpatterns=[
    url(r'^sendsms/(?P<id>[\d]+)/$', sendsms, name = 'sendsms'),
]
  • Edit the views.py file:
nano myapp/myapp/views.py
def sendsms(request, id):
    #if request.method == 'POST' and 'send_a_sms' in request.POST:
        User = user.objects.get(id=id)
        name = User.name
        phone = User.phone
        from send_sms import sms
        try:
            sms(name,phone)
        except TwilioRestException as e:
            return HttpResponse("TwilioRestException" + str(e))
        except Exception as ex:
            return HttpResponse("Exception" + str(ex))
        return redirect("/home")
  • Edit the sendsms.py file:
nano myapp/sendsms.py
from twilio.rest import Client
from myapp.models import message_format
import os

def sms(name,phone):

    account_sid = os.environ['TWILIO_ACCOUNT_SID']
    auth_token = os.environ['TWILIO_AUTH_TOKEN']
    client = Client(account_sid, auth_token)
    Message = str(message_format.objects.latest('id'))
    First_part = Message.split('%s')[0]
    Last_part = Message.split('%s')[-1]
    Body = First_part + name + Last_part
    To='+91'+'%s' %phone

    message = client.messages.create(
             body=Body,\
             from_='+15103984676',\
             to=To)
    return message.sid
  • Edit the home.html template file:
nano myapp/myapp/templates/home.html
<body>
  <table>
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Phone</th>
        <th>Actions</th>
    </tr>
    {% if user_list %}
       {{ user_list|length }} records found:<br><br>
       {% for item in user_list %}
        <tr>
           <td>{{ item.id }}</td>
           <td>{{ item.name }}</td>
           <td>{{ item.phone }}</td>
           <td>
               <a href="/sendsms/{{ item.id }}/">SMS</a>
           </td>
        </tr>
       {% empty %}
         No user added
       {% endfor %}
    {% else %}
       There are no records in the system
    {% endif %}
  </table>
</body>

Using Header & Footer

  • Create a new template file base.html:
nano myapp/myapp/templates/base.html
<header>
<style>
  h1 {
    color: white;
    background-color: black;
    font-family: verdana;
    font-size: 300%;
  }
  p {
  }
</style>
<h1>
   <center>
     Reminder App
   </center>
</h1>
{% block content %}{% endblock %}
</header>

<footer>
</footer>
  • Edit the template files:
nano myapp/myapp/templates/base.html
<!DOCTYPE html>
<html>
    <head>
      <title>Home Page</title>
       {% extends "base.html" %}
       {% block content %}
    </head>
       <body>
       ...
        </body>
       {% endblock %}
</html>

Deploy Django project

Source: tutorialspoint.com

 cd ~
 django-admin startproject myproject
 cd myproject
 python3 manage.py startapp myapp
 python3 manage.py migrate
 python3 manage.py createsuperuser

 nano myproject/urls.py
from django.conf.urls import include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns=[
    url(r'^admin/', admin.site.urls),
]
python3 manage.py runserver 0.0.0.0:8000
http://10.79.111.191:8000/admin/
Create Views
cd ~/myproject/myapp/
nano views.py
from django.http import HttpResponse

def hello(request):
   text = "<h1>welcome to my app number</h1>"
   return HttpResponse(text)
URL Mapping
nano ~/myproject/myproject/urls.py
from myapp.views import hello

urlpatterns=[
    url(r'^admin/', admin.site.urls),
    url(r'^hello/', hello, name = 'hello'),
]

Test Page:

http://10.79.111.191:8000/hello/
Organizing Your URLs
nano ~/myproject/myproject/urls.py 

Delete below lines:

from django.conf.urls import include, url
from myapp.views import hello

urlpatterns=[
    url(r'^admin/', admin.site.urls),
    url(r'^hello/', hello, name = 'hello'),
]

Add below lines:

from django.contrib import admin
from django.urls import include, path
from myapp import urls

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'^myapp/', include('myapp.urls')),
]

Create a new urls.py file for the App and paste above lines:

cd ~/myproject/myapp/
nano urls.py 
from django.conf.urls import include, url
from myapp.views import hello

from django.contrib import admin
admin.autodiscover()

urlpatterns=[
    url(r'^admin/', admin.site.urls),
    url(r'^hello/', hello, name = 'hello'),
]





References





{{#widget:DISQUS |id=networkm |uniqid=Django |url=https://aman.awiki.org/wiki/Django }}