article

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 %}

Related Post