Fading Coder

One Final Commit for the Last Sprint

Home > Tools > Content

Enhancing Django Blog with Custom ModelForms and Article Editing Support

Tools 1

Replacing Default Forms with Styled ModelForms

To improve the appearance and usability of the article creation interface, replace Django’s auto-generated form with a custom ModelForm that integrates Bootstrap styling. Begin by creating a new file blog/forms.py:

from django import forms
from blog.models import Article


class ArticleCreationForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['title', 'author', 'summary', 'content']
        labels = {
            'title': 'Article Title',
            'author': 'Author Name',
            'summary': 'Brief Summary',
            'content': 'Full Content'
        }
        widgets = {
            'title': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Enter a descriptive title'
            }),
            'author': forms.Select(attrs={'class': 'form-select'}),
            'summary': forms.TextInput(attrs={
                'class': 'form-control',
                'placeholder': 'Summarize the main idea in one sentence'
            }),
            'content': forms.Textarea(attrs={
                'class': 'form-control',
                'rows': 12,
                'placeholder': 'Write your article using Markdown syntax'
            })
        }

This form explicitly maps each field to a Bootstrap-styled widget, ensuring consistent visual treatment across inputs. The TextInput and Textarea widgets include semantic placeholder attributes for improved UX, while Select uses form-select for native dropdown styling.

Update templates/article_add.html to render the customizde form:

{% extends 'base.html' %}

{% block title %}New Article{% endblock %}

{% block content %}
<h1>Create a New Post</h1>
<form method="post" class="mt-4">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-success mt-3">Publish Article</button>
</form>
{% endblock %}

The as_p randering method wraps each field in <p> tags, preserving spacing and alignment without requiring menual HTML structure.

Implementing Article Update Functionality

Leverage Django’s generic UpdateView to support editing existing articles. In blog/views.py, add:

from django.views.generic import ListView, DetailView, CreateView, UpdateView
from blog.models import Article
from blog.forms import ArticleCreationForm

# ... existing view classes ...

class ArticleUpdateView(UpdateView):
    model = Article
    form_class = ArticleCreationForm
    template_name = 'article_edit.html'
    context_object_name = 'article'

Create templates/article_edit.html:

{% extends 'base.html' %}

{% block title %}Edit Article{% endblock %}

{% block content %}
<h1>Edit "{{ article.title }}"</h1>
<form method="post" class="mt-4">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-primary mt-3">Save Changes</button>
    <a href="{% url 'detial_article' article.pk %}" class="btn btn-secondary mt-3 ms-2">Cancel</a>
</form>
{% endblock %}

Register the new route in blog/urls.py:

from django.urls import path
from blog import views

urlpatterns = [
    path('', views.HomeView.as_view(), name='home'),
    path('article/<int:pk>/', views.ArticleDetailView.as_view(), name='detial_article'),
    path('add_article/', views.AddArticleView.as_view(), name='add_article'),
    path('article/edit/<int:pk>/', views.ArticleUpdateView.as_view(), name='edit_article'),
]

Finally, expose the edit action in templates/article_detail.html by adding an inline edit link beneath the author information:

<div class="d-flex justify-content-between align-items-center mb-4">
    <div>By {{ article.author }} on {{ article.created_at|date:"M d, Y" }}</div>
    <a href="{% url 'edit_article' article.pk %}" class="btn btn-outline-primary btn-sm">
        <i class="bi bi-pencil-square"></i> Edit
    </a>
</div>

This implementation ensures seamless transitions between viewing and editing states while maintaining responsive, accessible form controls powered by Bootstrap.

Related Articles

Efficient Usage of HTTP Client in IntelliJ IDEA

IntelliJ IDEA incorporates a versatile HTTP client tool, enabling developres to interact with RESTful services and APIs effectively with in the editor. This functionality streamlines workflows, replac...

Installing CocoaPods on macOS Catalina (10.15) Using a User-Managed Ruby

System Ruby on macOS 10.15 frequently fails to build native gems required by CocoaPods (for example, ffi), leading to errors like: ERROR: Failed to build gem native extension checking for ffi.h... no...

Resolve PhpStorm "Interpreter is not specified or invalid" on WAMP (Windows)

Symptom PhpStorm displays: "Interpreter is not specified or invalid. Press ‘Fix’ to edit your project configuration." This occurs when the IDE cannot locate a valid PHP CLI executable or when the debu...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.