article

Friday, May 29, 2020

Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json


Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json

CRUD, it stand for Create Read Update Delete.


Models.py
 
#models.py
from django.db import models
 
class Product(models.Model):
    FILLOW = 1
    FOOD = 2
    TOYS = 3
    PRODUCT_TYPES = (
        (FILLOW, 'Pillow'),
        (FOOD, 'Food'),
        (TOYS, 'Toys'),
    )
    name = models.CharField(max_length=50)
    dateadded = models.DateField(blank=True, null=True)
    productcode = models.CharField(max_length=30, blank=True)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    quantity = models.IntegerField(blank=True, null=True)
    category_type = models.PositiveSmallIntegerField(choices=PRODUCT_TYPES, blank=True, null=True)
  
    class Meta:  
        db_table = "myapp_product"
Database Table
CREATE TABLE myapp_product (
id INTEGER PRIMARY KEY,
name STRING (200),
productcode STRING (150),
price INTEGER,
quantity INTEGER,
category_type STRING (50),
dateadded DATE
);
Views.py
 
#views.py
from django.shortcuts import render, redirect, get_object_or_404

from myapp.models import Product
from myapp.forms import ProductForm

from django.http import JsonResponse
from django.template.loader import render_to_string


def index(request):
    return render(request, 'index.html')
 
def product_list(request):
    products = Product.objects.all()
    return render(request, 'product_list.html', {'products': products})


def save_product_form(request, form, template_name):
    data = dict()
    if request.method == 'POST':
        if form.is_valid():
            form.save()
            data['form_is_valid'] = True
            products = Product.objects.all()
            data['html_product_list'] = render_to_string('includes/partial_product_list.html', {
                'products': products
            })
        else:
            data['form_is_valid'] = False
    context = {'form': form}
    data['html_form'] = render_to_string(template_name, context, request=request)
    return JsonResponse(data)


def product_create(request):
    if request.method == 'POST':
        form = ProductForm(request.POST)
    else:
        form = ProductForm()
    return save_product_form(request, form, 'includes/partial_product_create.html')


def product_update(request, pk):
    product = get_object_or_404(Product, pk=pk)
    if request.method == 'POST':
        form = ProductForm(request.POST, instance=product)
    else:
        form = ProductForm(instance=product)
    return save_product_form(request, form, 'includes/partial_product_update.html')


def product_delete(request, pk):
    product = get_object_or_404(Product, pk=pk)
    data = dict()
    if request.method == 'POST':
        product.delete()
        data['form_is_valid'] = True
        products = Product.objects.all()
        data['html_product_list'] = render_to_string('includes/partial_product_list.html', {
            'products': products
        })
    else:
        context = {'product': product}
        data['html_form'] = render_to_string('includes/partial_product_delete.html', context, request=request)
    return JsonResponse(data)
forms.py
 
#forms.py
from django import forms
from myapp.models import Product
 
class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ('name', 'dateadded', 'productcode', 'price', 'quantity', 'category_type', )
urls.py
 
#urls.py
from django.contrib import admin  
from django.urls import path
from myapp import views  
from django.conf.urls import url

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('',views.index),
 url(r'^products/$', views.product_list, name='product_list'),
 url(r'^create/$', views.product_create, name='product_create'),
    url(r'^products/(?P\d+)/update/$', views.product_update, name='product_update'),
    url(r'^products/(?P\d+)/delete/$', views.product_delete, name='product_delete'),
]
settings.py pip install django-widget-tweaks
#settings.py 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp', 
    'widget_tweaks', #pip install django-widget-tweaks
]
//templates/index.html
{% extends 'base.html' %}

{% block content %}
  <h1 class="page-header">Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json</h1>

  <p class="lead">See the example clicking in the Product menu.</p>
  <p class="lead"><a href="/products">Product List</a>.</p>
{% endblock %}
//templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.css' %}"/>
    <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1"/>
 <title>{% block title %}Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json{% endblock %}</title>
 <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
</head>
<body>
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <a class="navbar-brand">Cairocoders</a>
        </div>
    </nav>
 
 <div class="container">
    <div class="col-md-12 well">
        <h3 class="text-primary">Django How to Implement CRUD (Create Read Update Delete) Using Ajax and Json</h3>
        <hr style="border-top:1px dotted #ccc;"/>
        {% block content %}
  
        {% endblock %}
    </div>
    </div>
    <script src="{% static 'js/jquery-3.1.1.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
    {% block javascript %} {% endblock %}
</body>
</html>
//templates/product_list.html
{% extends 'base.html' %}

{% load static %}

{% block javascript %}
  <script src="{% static 'js/script.js' %}"></script>
{% endblock %}

{% block content %}
  <h1 class="page-header">Products</h1>
  <p>
    <button type="button" class="btn btn-primary js-create-product" data-url="{% url 'product_create' %}">
      <span class="glyphicon glyphicon-plus"></span>
      New Product
    </button>
  </p>
  <table class="table" id="product-table">
    <thead>
      <tr>
        <th>#</th>
        <th>Name</th>
        <th>Date Added</th>
        <th>Category</th>
        <th>Product Code</th>
        <th>Quantiry</th>
        <th>Price</th>
        <th></th>
      </tr>
    </thead>
    <tbody>
      {% include 'includes/partial_product_list.html' %}
    </tbody>
  </table>
  <div class="modal fade" id="modal-product">
    <div class="modal-dialog">
      <div class="modal-content">

      </div>
    </div>
  </div>
{% endblock %}
//templates/includes/partial_product_create.html
<form method="post" action="{% url 'product_create' %}" class="js-product-create-form">
  {% csrf_token %}
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
      <span aria-hidden="true">×</span>
    </button>
    <h4 class="modal-title">Create a new product</h4>
  </div>
  <div class="modal-body">
    {% include 'includes/partial_product_form.html' %}
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    <button type="submit" class="btn btn-primary">Create product</button>
  </div>
</form>
//templates/includes/partial_product_delete.html
<form method="post" action="{% url 'product_delete' product.id %}" class="js-product-delete-form">
  {% csrf_token %}
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
      <span aria-hidden="true">×</span>
    </button>
    <h4 class="modal-title">Confirm product deletion</h4>
  </div>
  <div class="modal-body">
    <p class="lead">Are you sure you want to delete the product <strong>{{ product.name }}</strong>?</p>
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    <button type="submit" class="btn btn-danger">Delete product</button>
  </div>
</form>
//templates/includes/partial_product_form.html
{% load widget_tweaks %}

{% for field in form %}
  <div class="form-group{% if field.errors %} has-error{% endif %}">
    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
    {% render_field field class="form-control" %}
    {% for error in field.errors %}
      <p class="help-block">{{ error }}</p>
    {% endfor %}
  </div>
{% endfor %}
//templates/includes/partial_product_list.html
{% for product in products %}
  <tr>
    <td>{{ product.id }}</td>
    <td>{{ product.name }}</td>
    <td>{{ product.dateadded }}</td>
    <td>{{ product.get_category_type_display }}</td>
    <td>{{ product.productcode }}</td>
    <td>{{ product.quantity }}</td>
    <td>{{ product.price }}</td>
    <td style="width: 150px">
      <button type="button"
              class="btn btn-warning btn-sm js-update-product"
              data-url="{% url 'product_update' product.id %}">
        <span class="glyphicon glyphicon-pencil"></span> Edit
      </button>
      <button type="button"
              class="btn btn-danger btn-sm js-delete-product"
              data-url="{% url 'product_delete' product.id %}">
        <span class="glyphicon glyphicon-trash"></span> Delete
      </button>
    </td>
  </tr>
{% empty %}
  <tr>
    <td colspan="8" class="text-center bg-warning">No product</td>
  </tr>
{% endfor %}
//templates/includes/partial_product_update
<form method="post" action="{% url 'product_update' form.instance.pk %}" class="js-product-update-form">
  {% csrf_token %}
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
      <span aria-hidden="true">×</span>
    </button>
    <h4 class="modal-title">Update product</h4>
  </div>
  <div class="modal-body">
    {% include 'includes/partial_product_form.html' %}
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    <button type="submit" class="btn btn-primary">Update product</button>
  </div>
</form>
//static/js/script.js
$(document).ready(function(){
  var loadForm = function () { 
    var btn = $(this);
    $.ajax({
      url: btn.attr("data-url"),
      type: 'get',
      dataType: 'json',
      beforeSend: function () {
        $("#modal-product .modal-content").html("");
        $("#modal-product").modal("show");
      },
      success: function (data) {
        $("#modal-product .modal-content").html(data.html_form);
      }
    });
  };

  var saveForm = function () {
    var form = $(this);
    $.ajax({
      url: form.attr("action"),
      data: form.serialize(),
      type: form.attr("method"),
      dataType: 'json',
      success: function (data) {
        if (data.form_is_valid) {
          $("#product-table tbody").html(data.html_product_list);
          $("#modal-product").modal("hide");
        }
        else {
          $("#modal-product .modal-content").html(data.html_form);
        }
      }
    });
    return false;
  };


  /* Binding */
  $(".js-create-product").click(loadForm);
  $("#modal-product").on("submit", ".js-product-create-form", saveForm);

  // Update product
  $("#product-table").on("click", ".js-update-product", loadForm);
  $("#modal-product").on("submit", ".js-product-update-form", saveForm);

  // Delete product
  $("#product-table").on("click", ".js-delete-product", loadForm);
  $("#modal-product").on("submit", ".js-product-delete-form", saveForm);

});

Sunday, May 24, 2020

Change Password - How to Use Django Messages Framework


Change Password - How to Use Django Messages Framework

Django project already comes with the messages framework installed.  In this article I will show How to Use Django Messages Framework

INSTALLED_APPS
django.contrib.messages

MIDDLEWARE or MIDDLEWARE_CLASSES in older versions:
django.contrib.sessions.middleware.SessionMiddleware
django.contrib.messages.middleware.MessageMiddleware

TEMPLATES
context_processors
django.contrib.messages.context_processors.messages

Settings.py
#settings.py
from django.contrib.messages import constants as messages

MESSAGE_TAGS = {
    messages.DEBUG: 'alert-info',
    messages.INFO: 'alert-info',
    messages.SUCCESS: 'alert-success',
    messages.WARNING: 'alert-warning',
    messages.ERROR: 'alert-danger',
}
Usage views.py
#views.py
from django.shortcuts import render, redirect

from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm
 
@login_required
def password(request):
    if request.method == 'POST':
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            update_session_auth_hash(request, user)  # Important!
            messages.success(request, 'Your password was successfully updated!')
            return redirect('/password')
        else:
            messages.error(request, 'Please correct the error below.')
    else:
        form = PasswordChangeForm(request.user)
    return render(request, 'change_password.html', {'form': form })
the template change_password.html
//templates/change_password.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>{% block title %} Change Password {% endblock title %}</title>
  {% load static %} 
</head>
<body>
<div style="padding:25px;">
<p><h1>Change Password - How to Use Django Messages Framework</h1></p>
{% if messages %}
  <ul class="messages">
    {% for message in messages %}
      <li class="{{ message.tags }}">{{ message }}</li>
    {% endfor %}
  </ul>
{% endif %}
<form method="post">
  {% csrf_token %}
  {{ form }}
  <button type="submit">Save changes</button>
</form>
</div>
<style>
ul {list-style:none;}
.alert-success, .alert-warning, .alert-info, .alert-danger {
 background-repeat: no-repeat;
 background-position: 10px center;
 height: 20px;
 text-transform: uppercase;
 font-size: 11px;
 line-height: 22px;
 margin-bottom: 20px;
 padding-top: 10px;
 padding-right: 10px;
 padding-bottom: 10px;
 padding-left: 50px;
 
}
.alert-success     {
 background-color: #EBF8D6;
 border: 1px solid #A6DD88;
 color: #539B2D;
 background-image: url({% static 'img/accept00.png' %});
}
.alert-warning      {
 background-color: #FFECE6;
 border: 1px solid #FF936F;
 color: #842100;
 background-image: url({% static 'img/delete00.png' %});
}
.alert-info    {
 background-color: #D3EEF1;
 border: 1px solid #81CDD8;
 color: #369CAB;
 background-image: url({% static 'img/info0000.png' %});
}
.alert-danger   {
 background-color: #FFFBCC;
 border: 1px solid #FFF35E;
 color: #C69E00;
 background-image: url({% static 'img/warning0.png' %});
}
.close-notification     {
 width: 16px;
 height: 16px;
 position: absolute;
 background: url({% static 'img/close000.png' %}) no-repeat;
 top: 4px;
 right: 4px;
 cursor: pointer;
}
</style>
</body>
</html>
//If the error message was added, the output would be something like that:
<ul class="messages">
    <li class="alert-danger">Please correct the error below.</li>
</ul>
 
#urls.py
from django.contrib import admin  
from django.urls import path
from myapp import views  
from django.conf.urls import url

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('password',views.password),
]

Django How to Use django-import-export


Django How to Use django-import-export

The django-import-export library supports multiple formats, including xls, csv, json, yaml, and all other formats

Installation

pip install django-import-export

Update your settings.py:

INSTALLED_APPS = (
    ...
    'import_export',

) models.py
#models.py
from django.db import models
 
class Member(models.Model):
    firstname = models.CharField(max_length=200)
    lastname = models.CharField(max_length=200)
    email = models.EmailField(blank=True)
    birth_date = models.DateField()
    contact = models.CharField(max_length=100, blank=True)
  
    class Meta:  
        db_table = "web_member"
resources.py
#resources.py
from import_export import resources
from myapp.models import Member

class MemberResource(resources.ModelResource):
    class Meta:
        model = Member
Django Admin
use ImportExportModelAdmin instead of ModelAdmin. admin.py
#admin.py
from django.contrib import admin

from import_export.admin import ImportExportModelAdmin
from myapp.models import Member

@admin.register(Member)
class MemberAdmin(ImportExportModelAdmin):
    list_display = ("firstname", "lastname", "email", "birth_date")
    pass
#urls.py
from django.contrib import admin  
from django.urls import path
from myapp import views  
from django.conf.urls import url

urlpatterns = [  
    path('admin/', admin.site.urls),  
    #path('',views.index),
 url(r'^export-exl/$', views.export, name='export'),
 url(r'^export-csv/$', views.export, name='export'),
]
Views.py
#views.py
from django.shortcuts import render, redirect
 
from django.http import HttpResponse
from myapp.resources import MemberResource


def export(request):
    member_resource = MemberResource()
    dataset = member_resource.export()
    #response = HttpResponse(dataset.csv, content_type='text/csv')
    #response['Content-Disposition'] = 'attachment; filename="member.csv"'
    #response = HttpResponse(dataset.json, content_type='application/json')
    #response['Content-Disposition'] = 'attachment; filename="persons.json"'
    response = HttpResponse(dataset.xls, content_type='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename="persons.xls"' 
    return response

Saturday, May 23, 2020

Django Export to PDF - display PDF in the browser and open-save file example


Django Export to PDF - display PDF in the browser and open-save file example

In this article I will show how to return a PDF response, which can also be used if you are just serving an existing PDF file

below  Django’s FileSystemStorage class FileSystemStorage sets the base_url to the project’s MEDIA_ROOT.

View.py
#views.py
from django.shortcuts import render, redirect
 
from django.core.files.storage import FileSystemStorage
from django.http import HttpResponse, HttpResponseNotFound

def pdf_view(request):
    fs = FileSystemStorage()
    filename = 'mypdf.pdf'
    if fs.exists(filename):
        with fs.open(filename) as pdf:
            response = HttpResponse(pdf, content_type='application/pdf')
            #response['Content-Disposition'] = 'attachment; filename="mypdf.pdf"' #user will be prompted with the browser’s open/save file
            response['Content-Disposition'] = 'inline; filename="mypdf.pdf"' #user will be prompted display the PDF in the browser
            return response
    else:
        return HttpResponseNotFound('The requested pdf was not found in our server.')
urls.py
#urls.py
from django.contrib import admin  
from django.urls import path
from myapp import views  
from django.conf.urls import url

urlpatterns = [  
    path('admin/', admin.site.urls),  
    #path('',views.index),
 url(r'^view-pdf/$', views.pdf_view, name='pdf_view'),
]
url : http://127.0.0.1:8000/view-pdf/

Django How to Create Change Password User


Django How to Create Change Password User

change password view using the built-in PasswordChangeForm


views.py
 
#views.py
from django.shortcuts import render, redirect
 
from django.contrib import messages
from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm

def change_password(request):
    if request.method == 'POST':
        form = PasswordChangeForm(request.user, request.POST)
        if form.is_valid():
            user = form.save()
            update_session_auth_hash(request, user)  # Important!
            messages.success(request, 'Your password was successfully updated!')
            return redirect('/password')
        else:
            messages.error(request, 'Please correct the error below.')
    else:
        form = PasswordChangeForm(request.user)
    return render(request, 'change_password.html', {'form': form })
urls.py
 
#urls.py
from django.contrib import admin  
from django.urls import path
from myapp import views  
from django.conf.urls import url

urlpatterns = [  
    path('admin/', admin.site.urls),  
    #path('',views.index),
 url(r'^password/$', views.change_password, name='change_password'),
]
change_password.html
//templates/change_password.html
<form method="post">
  {% csrf_token %}
  {{ form }}
  <button type="submit">Save changes</button>
</form>

First login using your account then
Run : http://127.0.0.1:8000/password/ to change password



Friday, May 22, 2020

Django How To Upload Images using Pillow Python Imaging Library


Django How To Upload Images using Pillow Python Imaging Library

In this article, we will learn how to upload images in a Django application using Pillow Python Imaging Library. https://pypi.org/project/Pillow/

models.py



 
#models.py
from django.db import models
 
class Image(models.Model):
    title = models.CharField(max_length=200)
    image = models.ImageField(upload_to='images')

    def __str__(self):
        return self.title
  
    class Meta:  
        db_table = "myapp_image"
The upload_to parameters specify the location where images will be stored which for this model is MEDIA_ROOT/images/

Install Pillow by running the following command in your shell.

pip install Pillow

settings.py

# Base url to serve media files
MEDIA_URL = '/media/'

# Path where media is stored

MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

urls.py file
 
#urls.py
from django.contrib import admin  
from django.urls import path
from myapp import views  

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('',views.index),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
forms.py
 
#forms.py
from django import forms
from myapp.models import Image


class ImageForm(forms.ModelForm):
    """Form for the image model"""
    class Meta:
        model = Image
        fields = ('title', 'image')
 
#views.py
from django.shortcuts import render, redirect

from myapp.forms import ImageForm

def index(request):
    """Process images uploaded by users"""
    if request.method == 'POST':
        form = ImageForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            # Get the current instance object to display in the template
            img_obj = form.instance
            return render(request, 'index.html', {'form': form, 'img_obj': img_obj})
    else:
        form = ImageForm()
    return render(request, 'index.html', {'form': form})
//templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">
  <title>upload imagae</title>
</head>
<body>
<p><h1>Django How To Upload Images using Pillow Python Imaging Library</h1></p>
<p><h4>pip install Pillow</h4></p>
<form method="post" enctype="multipart/form-data">
  {% csrf_token %}
   {{ form.as_p }}
  <button type="submit">Upload</button>
</form>

{% if img_obj %}
  <h3>Succesfully uploaded : {{img_obj.title}}</h3>
  <img src="{{ img_obj.image.url}}" alt="connect" style="max-height:300px">
{% endif %}

</body>
</html>

Django How to create Sitemaps for the blog application


Django How to create Sitemaps for the blog application

sitemap is an XML file that informs search engines such as Google, the pages of your website, their relevance, and how frequently they are updated.


sitemap plays a crucial role in modern SEO (Search Engine Optimization).

In this article, we will learn how to create sitemaps for the blog application

Installation
Add 'django.contrib.sitemaps' in INSTALLED_APPS setting setting.py
INSTALLED_APPS += ( 'django.contrib.sitemaps',)

Part 1 : Django Build a blog application with bootstrap and Automatically Generate slugs

https://tutorial101.blogspot.com/2020/05/django-build-blog-application-with.html

Part 2 : Django Build a blog application Part 2 with WYSIWYG Editor Pagination and Comments


https://tutorial101.blogspot.com/2020/05/django-build-blog-application-part-2.html




 
#models.py
from django.db import models
 
from django.contrib.auth.models import User
from django.utils.text import slugify

STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='myapp_post')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
 
    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title
  
    def get_absolute_url(self):
        from django.urls import reverse
        return reverse("post_detail", kwargs={"slug": str(self.slug)})
  
    class Meta:  
        db_table = "myapp_post"
  
    def save(self, *args, **kwargs):
        value = self.title
        self.slug = slugify(value, allow_unicode=True)
        super().save(*args, **kwargs)
create a new file sitemaps.pyand add the following
 
#sitemaps.py
from django.contrib.sitemaps import Sitemap
from myapp.models import Post

class PostSitemap(Sitemap):
    changefreq = "weekly"
    priority = 0.8

    def items(self):
        return Post.objects.filter(status=1)

    def lastmod(self, obj):
        return obj.updated_on
optional changefreq and priority attributes indicate the change frequency of post

Possible values for changefreq, whether you use a method or attribute, are:

‘always’
‘hourly’
‘daily’
‘weekly’
‘monthly’
‘yearly’
‘never’

Sitemap.py

from django.contrib.sitemaps.views import sitemap
from myapp.sitemaps import PostSitemap


sitemaps = {
    "posts": PostSitemap,
}

urlpatterns = [
        ..........
    path("sitemap.xml", sitemap, {"sitemaps": sitemaps}, name="sitemap"),
        .........
]

run the server and visit http://127.0.0.1:8000/sitemap.xml

To explore more visit – https://docs.djangoproject.com/en/3.0/ref/contrib/sitemaps/

Django how to create RSS feeds for the blog application


Django how to create RSS feeds for the blog application

RSS is an abbreviation for Really Simple Syndication, it’s a way to have information delivered to you instead of you having to go find it. RSS is basically a structured XML document that includes full or summarized text along with other metadata such as published date, author name, etc.

RSS is a web feed allows users and applications to access updates to websites in a standardized, computer-readable format.

In this article, we are going to generate feeds for a blog application

Part 1 : Django Build a blog application with bootstrap and Automatically Generate slugs

https://tutorial101.blogspot.com/2020/05/django-build-blog-application-with.html

Part 2 : Django Build a blog application Part 2 with WYSIWYG Editor Pagination and Comments

https://tutorial101.blogspot.com/2020/05/django-build-blog-application-part-2.html



 
#models.py
from django.db import models
 
from django.contrib.auth.models import User
from django.utils.text import slugify

STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='myapp_post')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
 
    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title
  
    def get_absolute_url(self):
        from django.urls import reverse
        return reverse("post_detail", kwargs={"slug": str(self.slug)})
  
    class Meta:  
        db_table = "myapp_post"
  
    def save(self, *args, **kwargs):
        value = self.title
        self.slug = slugify(value, allow_unicode=True)
        super().save(*args, **kwargs)
Create a new file feeds.py inside the application directory.
 
#feeds.py
from django.contrib.syndication.views import Feed
from django.template.defaultfilters import truncatewords
from myapp.models import Post
from django.urls import reverse


class LatestPostsFeed(Feed):
    title = "My blog"
    link = ""
    description = "New posts of my blog."

    def items(self):
        return Post.objects.filter(status=1)

    def item_title(self, item):
        return item.title

    def item_description(self, item):
        return truncatewords(item.content, 30)

    # Only needed if the model has no get_absolute_url method
    # def item_link(self, item):
    #     return reverse("post_detail", args=[item.slug])
The title, link, and description correspond to the standard RSS , <link> and <description> elements, respectively. <br/> map the feed in urls.py file.

from .feeds import LatestPostsFeed

urlpatterns = [
    path("feed/rss", LatestPostsFeed(), name="post_feed"),
               ]

RSS 2.0 feed at /feed/rss
navigate to http://127.0.0.1:8000/feed/rss you should see the XML file.

To explore more visit – https://docs.djangoproject.com/en/3.0/ref/contrib/syndication/

Wednesday, May 20, 2020

Django Build a blog application Part 2 with WYSIWYG Editor Pagination and Comments


Django Build a blog application Part 2 with WYSIWYG Editor Pagination and Comments

Part 1 Django Build a blog application with bootstrap and Automatically Generate slugs

https://tutorial101.blogspot.com/2020/05/django-build-blog-application-with.html
1. Django How to Integrate Summernote WYSIWYG Editor
Install django-summernote.

pip install django-summernote

2. Django How to Add Pagination to Blog Application

3. Django Creating Comments System to Blog Application
 
#models.py
from django.db import models
 
from django.contrib.auth.models import User
from django.utils.text import slugify

STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='myapp_post')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
 
    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title
  
    class Meta:  
        db_table = "myapp_post"
  
    def save(self, *args, **kwargs):
        value = self.title
        self.slug = slugify(value, allow_unicode=True)
        super().save(*args, **kwargs)

class Comment(models.Model):
    post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name='comments')
    name = models.CharField(max_length=80)
    email = models.EmailField()
    body = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    active = models.BooleanField(default=False)
 
    class Meta:
        ordering = ['created_on']

    def __str__(self):
        return 'Comment {} by {}'.format(self.body, self.name)
  
    class Meta:  
        db_table = "myapp_comment"
 
#admin.py
from django.contrib import admin

from myapp.models import Post, Comment 
from django_summernote.admin import SummernoteModelAdmin

#admin.site.register(Post)

class PostAdmin(SummernoteModelAdmin):
    list_display = ('title', 'slug', 'status','created_on')
    list_filter = ("status",)
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}
    summernote_fields = ('content',)
 
admin.site.register(Post, PostAdmin)

@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
    list_display = ('name', 'body', 'post', 'created_on', 'active')
    list_filter = ('active', 'created_on')
    search_fields = ('name', 'email', 'body')
    actions = ['approve_comments']

    def approve_comments(self, request, queryset):
        queryset.update(active=True)
 
#forms.py
from django import forms
from myapp.models import Comment


class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('name', 'email', 'body')
 
#views.py
from django.shortcuts import render, redirect

from django.views import generic
from myapp.models import Post

from myapp.forms import CommentForm
from django.shortcuts import render, get_object_or_404

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

def index(request):
    object_list = Post.objects.filter(status=1).order_by('-created_on')
    paginator = Paginator(object_list, 3)  # 3 posts in each page
    page = request.GET.get('page')
    try:
        post_list = paginator.page(page)
    except PageNotAnInteger:
            # If page is not an integer deliver the first page
        post_list = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        post_list = paginator.page(paginator.num_pages)
    return render(request,
                  'index.html',
                  {'page': page,
                   'post_list': post_list})
 
# class PostDetail(generic.DetailView):
    # model = Post
    # template_name = 'post_detail.html'
 
def post_detail(request, slug):
    template_name = 'post_detail.html'
    post = get_object_or_404(Post, slug=slug)
    comments = post.comments.filter(active=True)
    new_comment = None
    # Comment posted
    if request.method == 'POST':
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():

            # Create Comment object but don't save to database yet
            new_comment = comment_form.save(commit=False)
            # Assign the current post to the comment
            new_comment.post = post
            # Save the comment to the database
            new_comment.save()
    else:
        comment_form = CommentForm()

    return render(request, template_name, {'post': post,
                                           'comments': comments,
                                           'new_comment': new_comment,
                                           'comment_form': comment_form}) 
 
#urls.py
from django.contrib import admin  
from django.urls import path, include
from myapp import views  

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('',views.index),
 #path('/', views.PostDetail.as_view(), name='post_detail'),
    path('/', views.post_detail, name='post_detail'),
    path('summernote/', include('django_summernote.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
//templates/index.html
{% extends 'base.html' %}

{% block content %}
    {% for post in post_list %}    
  <div class="post-preview">
          <a href="{% url 'post_detail' post.slug  %}">
            <h2 class="post-title">
              {{ post.title }}
            </h2>
            <h3 class="post-subtitle">
              {{post.content|slice:":200" }}
            </h3>
          </a>
          <p class="post-meta">Posted by {{ post.author }} | {{ post.created_on}} </p>
        </div>
        <hr>
    {% endfor %}  

<div class="clearfix">
 {% if post_list.has_other_pages %}
   <nav aria-label="Page navigation conatiner">
   <ul class="pagination justify-content-center">
  {% if post_list.has_previous %}
  <li><a href="?page={{ post_list.previous_page_number }}" class="page-link">« PREV </a></li>
  {% endif %}
  {% if post_list.has_next %}
  <li><a href="?page={{ post_list.next_page_number }}" class="page-link"> NEXT »</a></li>
    {% endif %}
   </ul>
   </nav>
  {% endif %}
</div>
</div>
{% endblock %}
//templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">
  <title>{% block title %} Clean Blog - Start Bootstrap Theme {% endblock title %}</title>
  {% load static %} 
  <!-- Bootstrap core CSS -->
  <link href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
  <!-- Custom fonts for this template -->
  <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
  <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
  <!-- Custom styles for this template -->
  <link href="{% static 'css/clean-blog.min.css' %}" rel="stylesheet">
</head>
<body>
  <!-- Navigation -->
  <nav class="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav">
    <div class="container">
      <a class="navbar-brand" href="index.html">Start Bootstrap</a>
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
        Menu
        <i class="fas fa-bars"></i>
      </button>
      <div class="collapse navbar-collapse" id="navbarResponsive">
        <ul class="navbar-nav ml-auto">
          <li class="nav-item">
            <a class="nav-link" href="index.html">Home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="about.html">About</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="post.html">Sample Post</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="contact.html">Contact</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>

  <!-- Page Header -->
  <header class="masthead" style="background-image: url('{% static 'img/home-bg.jpg' %}')">
    <div class="overlay"></div>
    <div class="container">
      <div class="row">
        <div class="col-lg-8 col-md-10 mx-auto">
          <div class="site-heading">
            <h1>Clean Blog</h1>
            <span class="subheading">A Blog Theme by Start Bootstrap</span>
          </div>
        </div>
      </div>
    </div>
  </header>

  <!-- Main Content -->
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-md-10 mx-auto">
     {% block content %}
  
        {% endblock %}
      </div>
    </div>
  </div>

  <hr>

  <!-- Footer -->
  <footer>
    <div class="container">
      <div class="row">
        <div class="col-lg-8 col-md-10 mx-auto">
          <ul class="list-inline text-center">
            <li class="list-inline-item">
              <a href="#">
                <span class="fa-stack fa-lg">
                  <i class="fas fa-circle fa-stack-2x"></i>
                  <i class="fab fa-twitter fa-stack-1x fa-inverse"></i>
                </span>
              </a>
            </li>
            <li class="list-inline-item">
              <a href="#">
                <span class="fa-stack fa-lg">
                  <i class="fas fa-circle fa-stack-2x"></i>
                  <i class="fab fa-facebook-f fa-stack-1x fa-inverse"></i>
                </span>
              </a>
            </li>
            <li class="list-inline-item">
              <a href="#">
                <span class="fa-stack fa-lg">
                  <i class="fas fa-circle fa-stack-2x"></i>
                  <i class="fab fa-github fa-stack-1x fa-inverse"></i>
                </span>
              </a>
            </li>
          </ul>
          <p class="copyright text-muted">Copyright © Your Website 2020</p>
        </div>
      </div>
    </div>
  </footer>
  <!-- Bootstrap core JavaScript -->
  <script src="{% static 'vendor/jquery/jquery.min.js' %}"></script>
  <script src="{% static 'vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
  <!-- Custom scripts for this template -->
  <script src="{% static 'js/clean-blog.min.js' %}"></script>
</body>
</html>
//templates/post_detail.html
{% extends 'base.html' %}

{% block content %}
 <div class="card-body">
        <h1>{% block title %} {{ post.title }} {% endblock title %}</h1>
        <p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
        <p class="card-text ">{{ post.content | safe }}</p>
    </div>
 
 <h2>{{ comments.count }} comments</h2>
    {% for comment in comments %}
        <div class="comments" style="padding: 10px;">
          <p class="font-weight-bold">
            {{ comment.name }}
            <span class=" text-muted font-weight-normal">
              {{ comment.created_on }}
            </span>
          </p>
          {{ comment.body | linebreaks }}
    <hr/>
        </div>
        {% endfor %}
  
  
  <div class="card-body">
        {% if new_comment %}
        <div class="alert alert-success" role="alert">
          Your comment is awaiting moderation
        </div>
        {% else %}
        <h3>Leave a comment</h3>
        <form method="post" style="margin-top: 1.3em;">
          {{ comment_form.as_p }}
          {% csrf_token %}
          <button type="submit" class="btn btn-primary">Submit</button>
        </form>
        {% endif %}
  </div>
   
{% endblock %}

Tuesday, May 19, 2020

Django Creating Comments System to Blog Application


Django Creating Comments System to Blog Application

Django Build a blog application with bootstrap and Automatically Generate slugs

Comment Model

Open The models.py file of blog application and below the Post model create the Comment model.
 
#models.py
from django.db import models
 
from django.contrib.auth.models import User
from django.utils.text import slugify

STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='myapp_post')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
 
    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title
  
    class Meta:  
        db_table = "myapp_post"
  
    def save(self, *args, **kwargs):
        value = self.title
        self.slug = slugify(value, allow_unicode=True)
        super().save(*args, **kwargs)

class Comment(models.Model):
    post = models.ForeignKey(Post,on_delete=models.CASCADE,related_name='comments')
    name = models.CharField(max_length=80)
    email = models.EmailField()
    body = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    active = models.BooleanField(default=False)

    class Meta:
        ordering = ['created_on']

    def __str__(self):
        return 'Comment {} by {}'.format(self.body, self.name)
  
    class Meta:  
        db_table = "myapp_comment"

Database Table
CREATE TABLE myapp_comment (
id INTEGER PRIMARY KEY,
post_id INTEGER,
name STRING (250),
email STRING (200),
body TEXT,
created_on DATETIME,
active STRING (50)
);
we have a Foreign key relation that establishes a many-to-one relationship with the Post model

need to synchronize this comment model into the database by running migrations to reflects the changes in the database.

(django) $ python manage.py makemigrations
(django) $ python manage.py migrate

Adding Comments Model To The Administration Site
Open admins.py file and write the following code.
 
#admin.py
from django.contrib import admin

from myapp.models import Post, Comment 
from django_summernote.admin import SummernoteModelAdmin

#admin.site.register(Post)

class PostAdmin(SummernoteModelAdmin):
    list_display = ('title', 'slug', 'status','created_on')
    list_filter = ("status",)
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}
    summernote_fields = ('content',)
 
admin.site.register(Post, PostAdmin)

@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
    list_display = ('name', 'body', 'post', 'created_on', 'active')
    list_filter = ('active', 'created_on')
    search_fields = ('name', 'email', 'body')
    actions = ['approve_comments']

    def approve_comments(self, request, queryset):
        queryset.update(active=True)
Creating forms from models forms.py
 
#forms.py
from django import forms
from myapp.models import Comment


class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('name', 'email', 'body')
Building Views views.py
 
#views.py
from django.shortcuts import render, redirect

from django.views import generic
from myapp.models import Post

from myapp.forms import CommentForm
from django.shortcuts import render, get_object_or_404

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

def index(request):
    object_list = Post.objects.filter(status=1).order_by('-created_on')
    paginator = Paginator(object_list, 3)  # 3 posts in each page
    page = request.GET.get('page')
    try:
        post_list = paginator.page(page)
    except PageNotAnInteger:
            # If page is not an integer deliver the first page
        post_list = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        post_list = paginator.page(paginator.num_pages)
    return render(request,
                  'index.html',
                  {'page': page,
                   'post_list': post_list})
 
# class PostDetail(generic.DetailView):
    # model = Post
    # template_name = 'post_detail.html'
 
def post_detail(request, slug):
    template_name = 'post_detail.html'
    post = get_object_or_404(Post, slug=slug)
    comments = post.comments.filter(active=True)
    new_comment = None
    # Comment posted
    if request.method == 'POST':
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():

            # Create Comment object but don't save to database yet
            new_comment = comment_form.save(commit=False)
            # Assign the current post to the comment
            new_comment.post = post
            # Save the comment to the database
            new_comment.save()
    else:
        comment_form = CommentForm()

    return render(request, template_name, {'post': post,
                                           'comments': comments,
                                           'new_comment': new_comment,
                                           'comment_form': comment_form}) 
Adding URL patterns for Views
 
from django.contrib import admin  
from django.urls import path, include
from myapp import views  

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('',views.index),
 #path('/', views.PostDetail.as_view(), name='post_detail'),
    path('/', views.post_detail, name='post_detail'),
    path('summernote/', include('django_summernote.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Templates For The Views post_deatail.html
//templates/post_detail.html
{% extends 'base.html' %}

{% block content %}
 <div class="card-body">
        <h1>{% block title %} {{ post.title }} {% endblock title %}</h1>
        <p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
        <p class="card-text ">{{ post.content | safe }}</p>
    </div>
 
 <h2>{{ comments.count }} comments</h2>
    {% for comment in comments %}
        <div class="comments" style="padding: 10px;">
          <p class="font-weight-bold">
            {{ comment.name }}
            <span class=" text-muted font-weight-normal">
              {{ comment.created_on }}
            </span>
          </p>
          {{ comment.body | linebreaks }}
    <hr/>
        </div>
        {% endfor %}
  
  
  <div class="card-body">
        {% if new_comment %}
        <div class="alert alert-success" role="alert">
          Your comment is awaiting moderation
        </div>
        {% else %}
        <h3>Leave a comment</h3>
        <form method="post" style="margin-top: 1.3em;">
          {{ comment_form.as_p }}
          {% csrf_token %}
          <button type="submit" class="btn btn-primary">Submit</button>
        </form>
        {% endif %}
  </div>
   
{% endblock %}

Flask Login Logout using SQLAlchemy with remember me COOKIE_TIME_OUT and password hash


Flask Login Logout using SQLAlchemy with remember me COOKIE_TIME_OUT and password hash

Database Table

CREATE TABLE user (
id INTEGER PRIMARY KEY,
username VARCHAR (64),
email VARCHAR (120),
fullname STRING (255),
password_hash VARCHAR (128),
about_me STRING (140),
last_seen DATETIME

);



#app.py
from flask import Flask, render_template, url_for, request, session, flash, redirect, make_response
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime, timedelta
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)

app.config['PERMANENT_SESSION_LIFETIME'] =  timedelta(minutes=10)
global COOKIE_TIME_OUT
#COOKIE_TIME_OUT = 60*60*24*7 #7 days
COOKIE_TIME_OUT = 60*5 #5 minutes

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///devdb.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.secret_key = "caircocoders-ednalan-2020"

db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    fullname = db.Column(db.String(120), index=True, unique=True)
    password_hash = db.Column(db.String(128))
    about_me = db.Column(db.String(140))
    last_seen = db.Column(db.DateTime, default=datetime.utcnow)
 
    def __repr__(self):
        return ''.format(self.username)
  
@app.route('/')
def index():
 if 'email' in session:
  username_session = session['email']
  user_rs = User.query.filter_by(email=username_session).first()
  return render_template('index.html', user_rs=user_rs)
 else:
  return redirect('/login')

@app.route('/login')
def login():
    passwordhash = generate_password_hash('test2')
    print(passwordhash)
    return render_template('login.html')
  
@app.route('/submit', methods=['POST'])
def login_submit():
 _email = request.form['inputEmail']
 _password = request.form['inputPassword']
 _remember = request.form.getlist('inputRemember')
 
 if 'email' in request.cookies:
  username = request.cookies.get('email')
  password = request.cookies.get('pwd') 
  row = User.query.filter_by(email=username).first()
  if row and check_password_hash(row.password_hash, password):
   #print(username + ' ' + password)
   session['email'] = row.email
   return redirect('/')
  else:
   return redirect('/login')
 # validate the received values
 elif _email and _password:
  #check user exists   
  row = User.query.filter_by(email=_email).first()  
  if row:
   if check_password_hash(row.password_hash, _password):
    session['email'] = row.email
    if _remember:
     resp = make_response(redirect('/'))
     resp.set_cookie('email', _email, max_age=COOKIE_TIME_OUT)
     resp.set_cookie('pwd', _password, max_age=COOKIE_TIME_OUT)
     resp.set_cookie('rem', 'checked', max_age=COOKIE_TIME_OUT)
     return resp
    return redirect('/')
   else:
    flash('Invalid Password!')
    return redirect('/login')
  else:
   flash('Invalid Email Or Password!')
   return redirect('/login')   
  
 else:
  flash('Invalid Email Or Password!')
  return redirect('/login')
  
  
@app.route('/logout')
def logout():
 if 'email' in session:
  session.pop('email', None)
 return redirect('/')
 
if __name__ == '__main__':
 app.run(debug=True)
//templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Home</title>
</head>
<body>
<p align="center"><h1>Python Flask Login Logout</h1></p>
<p align="center"><h1>Hello : {{ user_rs.fullname }}</h1></p>
<p><h3><a href="{{ url_for('logout') }}">Log Out</a></h3></p>
</body>
</html>
//templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Login</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css">
</head>
<body>
<div class="container">
    <div class="card card-login mx-auto text-center bg-dark">
        <div class="card-header mx-auto bg-dark">
            <span> <img src="{{ url_for('static', filename='img/logologin.png') }}" class="w-75" alt="Logo"> </span><br/>
            <span class="logo_title mt-5"> Login Dashboard </span>
    <div>
     {% with messages = get_flashed_messages() %}
       {% if messages %}
      {% for message in messages %}
      <div class="alert alert-danger" role="alert">{{ message }}</div>
      {% endfor %}
       {% endif %}
     {% endwith %}
    </div>
        </div>
        <div class="card-body">
            <form method="post" action="/submit">
                <div class="input-group form-group">
                    <div class="input-group-prepend">
                        <span class="input-group-text"><i class="fas fa-user"></i></span>
                    </div>
                    <input type="text" name="inputEmail" class="form-control" value="{% if 'email' in request.cookies %} {{ request.cookies.get('email') }} {% endif %}" placeholder="Email Address">
                </div>

                <div class="input-group form-group">
                    <div class="input-group-prepend">
                        <span class="input-group-text"><i class="fas fa-key"></i></span>
                    </div>
                    <input type="password" name="inputPassword" class="form-control" value="{% if 'pwd' in request.cookies %} {{ request.cookies.get('pwd') }} {% endif %}" placeholder="Password">
                </div>
    
    <div class="input-group form-group">
       <div class="custom-control custom-checkbox">
     <input type="checkbox" name="inputRemember" checked="{% if 'rem' in request.cookies %} {{ request.cookies.get('rem') }} {% endif %}" autocomplete="off" class="custom-control-input" id="customControlInline">
     <label class="custom-control-label" for="customControlInline" style="color:#fff;">Remember me</label>
       </div>
    </div>
                <div class="form-group">
                    <input type="submit" name="btn" value="Login" class="btn btn-outline-danger float-right login_btn">
                </div>

            </form>
        </div>
    </div>
</div>
<style>
body {
            background: #17a2b8 !important;
        }
        .card {
            border: 1px solid #28a745;
        }
        .card-login {
            margin-top: 130px;
            padding: 18px;
            max-width: 30rem;
        }

        .card-header {
            color: #fff;
            /*background: #ff0000;*/
            font-family: sans-serif;
            font-size: 20px;
            font-weight: 600 !important;
            margin-top: 10px;
            border-bottom: 0;
        }

        .input-group-prepend span{
            width: 50px;
            background-color: #ff0000;
            color: #fff;
            border:0 !important;
        }

        input:focus{
            outline: 0 0 0 0  !important;
            box-shadow: 0 0 0 0 !important;
        }

        .login_btn{
            width: 130px;
        }

        .login_btn:hover{
            color: #fff;
            background-color: #ff0000;
        }

        .btn-outline-danger {
            color: #fff;
            font-size: 18px;
            background-color: #28a745;
            background-image: none;
            border-color: #28a745;
        }

        .form-control {
            display: block;
            width: 100%;
            height: calc(2.25rem + 2px);
            padding: 0.375rem 0.75rem;
            font-size: 1.2rem;
            line-height: 1.6;
            color: #28a745;
            background-color: transparent;
            background-clip: padding-box;
            border: 1px solid #28a745;
            border-radius: 0;
            transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
        }

        .input-group-text {
            display: -ms-flexbox;
            display: flex;
            -ms-flex-align: center;
            align-items: center;
            padding: 0.375rem 0.75rem;
            margin-bottom: 0;
            font-size: 1.5rem;
            font-weight: 700;
            line-height: 1.6;
            color: #495057;
            text-align: center;
            white-space: nowrap;
            background-color: #e9ecef;
            border: 1px solid #ced4da;
            border-radius: 0;
        }
</style>
</body>
</html>

Monday, May 18, 2020

Django How to Add Pagination to Blog Application


Django How to Add Pagination to Blog Application

Django Build a blog application with bootstrap and Automatically Generate slugs

#views.py
from django.shortcuts import render, redirect

from django.views import generic
from myapp.models import Post

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

def index(request):
    object_list = Post.objects.filter(status=1).order_by('-created_on')
    paginator = Paginator(object_list, 3)  # 3 posts in each page
    page = request.GET.get('page')
    try:
        post_list = paginator.page(page)
    except PageNotAnInteger:
            # If page is not an integer deliver the first page
        post_list = paginator.page(1)
    except EmptyPage:
        # If page is out of range deliver last page of results
        post_list = paginator.page(paginator.num_pages)
    return render(request,
                  'index.html',
                  {'page': page,
                   'post_list': post_list})
 
class PostDetail(generic.DetailView):
    model = Post
    template_name = 'post_detail.html'
//templates/index.html
{% extends 'base.html' %}

{% block content %}
    {% for post in post_list %}    
  <div class="post-preview">
          <a href="{% url 'post_detail' post.slug  %}">
            <h2 class="post-title">
              {{ post.title }}
            </h2>
            <h3 class="post-subtitle">
              {{post.content|slice:":200" }}
            </h3>
          </a>
          <p class="post-meta">Posted by {{ post.author }} | {{ post.created_on}} </p>
        </div>
        <hr>
    {% endfor %}  

<div class="clearfix">
 {% if post_list.has_other_pages %}
   <nav aria-label="Page navigation conatiner">
   <ul class="pagination justify-content-center">
  {% if post_list.has_previous %}
  <li><a href="?page={{ post_list.previous_page_number }}" class="page-link">« PREV </a></li>
  {% endif %}
  {% if post_list.has_next %}
  <li><a href="?page={{ post_list.next_page_number }}" class="page-link"> NEXT »</a></li>
    {% endif %}
   </ul>
   </nav>
  {% endif %}
</div>
</div>
{% endblock %}
 
#models.py
from django.db import models
 
from django.contrib.auth.models import User
from django.utils.text import slugify

STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='myapp_post')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
 
    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title
  
    class Meta:  
        db_table = "myapp_post"
  
    def save(self, *args, **kwargs):
        value = self.title
        self.slug = slugify(value, allow_unicode=True)
        super().save(*args, **kwargs)

Django How to Integrate Summernote WYSIWYG Editor


Django How to Integrate Summernote WYSIWYG Editor

A WYSIWYG (pronounced “wiz-ee-wig”) editor or program is one that allows a developer to see what the result will look like while the interface or document is being created. WYSIWYG is an acronym for “what you see is what you get”.

In this tutorial, we will go through the integration of the Summernote WYSIWYG HTML Editor in Django.

Install django-summernote.

pip install django-summernote

django_summernote to INSTALLED_APP in settings.py.

INSTALLED_APPS += ('django_summernote', ) 

django_summernote.urls to urls.py.

from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [ 
    path('admin/', admin.site.urls), 
    path('summernote/', include('django_summernote.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Media settings
X_FRAME_OPTIONS = 'SAMEORIGIN'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')


To explore more configuration read the official documentation of the package, https://github.com/summernote/django-summernote
#admin.py
from django.contrib import admin

from myapp.models import Post 
from django_summernote.admin import SummernoteModelAdmin

#admin.site.register(Post)

class PostAdmin(SummernoteModelAdmin):
    list_display = ('title', 'slug', 'status','created_on')
    list_filter = ("status",)
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}
    summernote_fields = ('content',)
 
admin.site.register(Post, PostAdmin)
#urls.py
from django.contrib import admin  
from django.urls import path, include
from myapp import views  

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('',views.index),
 path('/', views.PostDetail.as_view(), name='post_detail'),
    path('summernote/', include('django_summernote.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
#settings.py
INSTALLED_APPS += ('django_summernote', )

X_FRAME_OPTIONS = 'SAMEORIGIN'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

Sunday, May 17, 2020

Django Build a blog application with bootstrap and Automatically Generate slugs


Django Build a blog application with bootstrap and Automatically Generate slugs

Part 2 Django Build a blog application Part 2 with WYSIWYG Editor Pagination and Comments

In this tutorial, we’ll build a Blog application with Django that allows users to create, edit, and delete posts.

Also Generating slugs automatically like http://127.0.0.1:8000/6-ways-salesforce-gets-things-done-with-python/

Database Table
CREATE TABLE myapp_post (
    id         INTEGER      PRIMARY KEY,
    title      STRING (255),
    slug       STRING (200),
    author_id  INT (11),
    updated_on DATETIME,
    content    TEXT,
    created_on DATETIME,
    status     STRING (200)

);
 
#models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils.text import slugify

STATUS = (
    (0,"Draft"),
    (1,"Publish")
)

class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='myapp_post')
    updated_on = models.DateTimeField(auto_now= True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
 
    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title
  
    class Meta:  
        db_table = "myapp_post"
  
    def save(self, *args, **kwargs):
        value = self.title
        self.slug = slugify(value, allow_unicode=True)
        super().save(*args, **kwargs)
 
#admin.py
from django.contrib import admin

from myapp.models import Post 

#admin.site.register(Post)

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug', 'status','created_on')
    list_filter = ("status",)
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}
  
admin.site.register(Post, PostAdmin)
 
#urls.py
from django.contrib import admin  
from django.urls import path
from myapp import views  

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('',views.index),
 path('/', views.PostDetail.as_view(), name='post_detail'),
]
 
#views.py
from django.shortcuts import render, redirect

from django.views import generic
from myapp.models import Post

def index(request):
    post_list = Post.objects.filter(status=1).order_by('-created_on')
    return render(request, 'index.html', { 'post_list': post_list })
 
class PostDetail(generic.DetailView):
    model = Post
    template_name = 'post_detail.html'
//templates/index.html
{% extends 'base.html' %}

{% block content %}
    {% for post in post_list %}    
  <div class="post-preview">
          <a href="{% url 'post_detail' post.slug  %}">
            <h2 class="post-title">
              {{ post.title }}
            </h2>
            <h3 class="post-subtitle">
              {{post.content|slice:":200" }}
            </h3>
          </a>
          <p class="post-meta">Posted by {{ post.author }} | {{ post.created_on}} </p>
        </div>
        <hr>
    {% endfor %}    
        <div class="clearfix">
          <a class="btn btn-primary float-right" href="#">Older Posts →</a>
        </div>
{% endblock %}
//templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>Clean Blog - Start Bootstrap Theme</title>
  {% load static %} 
  <!-- Bootstrap core CSS -->
  <link href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">

  <!-- Custom fonts for this template -->
  <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
  <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

  <!-- Custom styles for this template -->
  <link href="{% static 'css/clean-blog.min.css' %}" rel="stylesheet">

</head>

<body>

  <!-- Navigation -->
  <nav class="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav">
    <div class="container">
      <a class="navbar-brand" href="index.html">Start Bootstrap</a>
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
        Menu
        <i class="fas fa-bars"></i>
      </button>
      <div class="collapse navbar-collapse" id="navbarResponsive">
        <ul class="navbar-nav ml-auto">
          <li class="nav-item">
            <a class="nav-link" href="index.html">Home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="about.html">About</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="post.html">Sample Post</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="contact.html">Contact</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>

  <!-- Page Header -->
  <header class="masthead" style="background-image: url('{% static 'img/home-bg.jpg' %}')">
    <div class="overlay"></div>
    <div class="container">
      <div class="row">
        <div class="col-lg-8 col-md-10 mx-auto">
          <div class="site-heading">
            <h1>Clean Blog</h1>
            <span class="subheading">A Blog Theme by Start Bootstrap</span>
          </div>
        </div>
      </div>
    </div>
  </header>

  <!-- Main Content -->
  <div class="container">
    <div class="row">
      <div class="col-lg-8 col-md-10 mx-auto">
     {% block content %}
  
        {% endblock %}
      </div>
    </div>
  </div>

  <hr>

  <!-- Footer -->
  <footer>
    <div class="container">
      <div class="row">
        <div class="col-lg-8 col-md-10 mx-auto">
          <ul class="list-inline text-center">
            <li class="list-inline-item">
              <a href="#">
                <span class="fa-stack fa-lg">
                  <i class="fas fa-circle fa-stack-2x"></i>
                  <i class="fab fa-twitter fa-stack-1x fa-inverse"></i>
                </span>
              </a>
            </li>
            <li class="list-inline-item">
              <a href="#">
                <span class="fa-stack fa-lg">
                  <i class="fas fa-circle fa-stack-2x"></i>
                  <i class="fab fa-facebook-f fa-stack-1x fa-inverse"></i>
                </span>
              </a>
            </li>
            <li class="list-inline-item">
              <a href="#">
                <span class="fa-stack fa-lg">
                  <i class="fas fa-circle fa-stack-2x"></i>
                  <i class="fab fa-github fa-stack-1x fa-inverse"></i>
                </span>
              </a>
            </li>
          </ul>
          <p class="copyright text-muted">Copyright © Your Website 2019</p>
        </div>
      </div>
    </div>
  </footer>

  <!-- Bootstrap core JavaScript -->
  <script src="{% static 'vendor/jquery/jquery.min.js' %}"></script>
  <script src="{% static 'vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script>

  <!-- Custom scripts for this template -->
  <script src="{% static 'js/clean-blog.min.js' %}"></script>

</body>

</html>
//templates/post_detail.html
{% extends 'base.html' %}

{% block content %}
<div class="col-lg-8 col-md-10 mx-auto">
    <h1>{% block title %} {{ object.title }} {% endblock title %}</h1>
    <p class=" text-muted">{{ post.author }} | {{ post.created_on }}</p>
    <p class="card-text ">{{ object.content | safe }}</p>
</div>
{% endblock %}

Wednesday, May 13, 2020

Django File Upload - How to upload file simple and Model Form


Django File Upload - How to upload file simple and Model Form

You will learn the conecepts django file upload

Need to set MEDIA_URL and MEDIA_ROOT in your project’s settings.py.

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')


MEDIA_URL in template you must add django.template.context_processors.media to your context_processeors inside the TEMPLATES config.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'templates')], 
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
'django.template.context_processors.media',
            ],
        },
    },
]
#view.py
from django.shortcuts import render, redirect

from django.conf import settings
from django.core.files.storage import FileSystemStorage

from myapp.models import Document
from myapp.forms import DocumentForm

def home(request):
    documents = Document.objects.all()
    return render(request, 'home.html', { 'documents': documents })


def simple_upload(request):
    if request.method == 'POST' and request.FILES['myfile']:
        myfile = request.FILES['myfile']
        fs = FileSystemStorage()
        filename = fs.save(myfile.name, myfile)
        uploaded_file_url = fs.url(filename)
        return render(request, 'simple_upload.html', {
            'uploaded_file_url': uploaded_file_url
        })
    return render(request, 'simple_upload.html')


def model_form_upload(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('/')
    else:
        form = DocumentForm()
    return render(request, 'model_form_upload.html', {
        'form': form
    })
#models.py
from django.db import models
 
class Document(models.Model):
    description = models.CharField(max_length=255, blank=True)
    document = models.FileField(upload_to='documents/')
    uploaded_at = models.DateTimeField(auto_now_add=True)
 
    class Meta:  
        db_table = "myapp_document"
#forms.py
from django import forms
from myapp.models import Document
 
class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = ('description', 'document', )
#urls.py
from django.contrib import admin  
from django.urls import path  
from myapp import views  

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('',views.home),
    path('simple_upload/',views.simple_upload),
    path('model_form_upload/',views.model_form_upload),
]
//templates/home.html
{% extends 'base.html' %}

{% block content %}
 <p><a href="/simple_upload" class="btn btn-primary">Simple Upload</a></p>
 <p><a href="/model_form_upload" class="btn btn-info">Model Form Upload</a></p>

 <p>Uploaded files:</p>
 <ul>
    {% for obj in documents %}
      <li>
        <a href="{{ obj.document.url }}">{{ obj.document.name }}</a>
        <small>(Uploaded at: {{ obj.uploaded_at }})</small>
      </li>
    {% endfor %}
 </ul>
{% endblock %}
//templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.css' %}"/>
    <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1"/>
 <title>{% block title %}Django File Upload{% endblock %}</title>
</head>
<body>
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <a class="navbar-brand">Cairocoders</a>
        </div>
    </nav>
 <div class="container">
    <div class="col-md-12 well">
        <h3 class="text-primary">Django File Upload - How to upload file simple and Model Form</h3>
        <hr style="border-top:1px dotted #ccc;"/>
        {% block content %}
 
        {% endblock %}
    </div>
    </div>
</body>
</html>
//templates/model_form_upload.html
{% extends 'base.html' %}

{% block content %}
  <form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-primary">Upload</button>
  </form>
<br/>
  <p><a href="/">Return to home</a></p>
{% endblock %}
//templates/simple_upload.html
{% extends 'base.html' %}

{% load static %}

{% block content %}
  <form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="myfile" class="form-control">
    <button type="submit" class="btn btn-primary">Upload</button>
  </form>

  {% if uploaded_file_url %}
    <p>File uploaded at: <a href="{{ uploaded_file_url }}">{{ uploaded_file_url }}</a></p>
  {% endif %}
<br/>
  <p><a href="/">Return to home</a></p>
{% endblock %}

Tuesday, May 12, 2020

Django Numbers and Dates Using Humanize - human readable format


Django Numbers and Dates Using Humanize - human readable format

humanize It is used to translate numbers and dates into a human readable format.

To install Django Humanize, add django.contrib.humanize to your INSTALLED_APPS setting:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
    'django.contrib.humanize',
]

Now in the template, load the template tags:

{% load humanize %}



 
#view.py
from django.shortcuts import render, redirect
import datetime

# Create your views here.
def index(request):
    now = datetime.datetime.now()
 
    context = {
  'spellone' : 8,
  'spellonetwo' : 1200000,
  'tree' : 8569,
  'four' : 85,
  'now' : now,
  'otherdate' : now + datetime.timedelta(days=1),
  'otherdatetime' : now + datetime.timedelta(days=1),
  'future' : now + datetime.timedelta(days=2542),
  'past' : now - datetime.timedelta(days=30)
    }
    return render(request, 'index.html', context)
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
    'django.contrib.humanize', 
]
 
from django.contrib import admin  
from django.urls import path  
from myapp import views  

urlpatterns = [  
    path('admin/', admin.site.urls),  
    path('',views.index),
]
//templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.css' %}"/>
    <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1"/>
 <title>{% block title %}Django Numbers and Dates Using Humanize - human readable format{% endblock %}</title>
</head>
<body>
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <a class="navbar-brand">Cairocoders</a>
        </div>
    </nav>
 <div class="container">
    <div class="col-md-12 well">
        <h3 class="text-primary">Django Numbers and Dates Using Humanize - human readable format</h3>
        <hr style="border-top:1px dotted #ccc;"/>
        {% block content %}
 
        {% endblock %}
    </div>
    </div>
</body>
</html>
//templates/index.html
{% extends 'base.html' %}

{% load humanize %}

{% block content %}

  <h3>Spell : {{ spellone|apnumber}} </h3>
  <h3>Spell : {{ spellonetwo|intword}} </h3>
  <h3>Commas : {{ tree|intcomma}} </h3>
  <h3>Ordinal : {{ four|ordinal}} </h3>
  <h3>Now : {{ now|naturalday}} </h3>
  <h3>Other Day : {{ otherdate|naturalday}} </h3>
  <h3>Other Day Time : {{ otherdatetime|naturaltime}} </h3>
  <h3>Future : {{ future }} </h3>
  <h3>Past : {{ past }} </h3>

{% endblock %}
Read more on the official Django Documentation https://docs.djangoproject.com/en/dev/ref/contrib/humanize/

Related Post