article

Saturday, May 9, 2020

Python Django Simple Forms Using Widget Tweaks


Python Django Simple Forms Using Widget Tweaks

Tweak the form field rendering in templates, not in python-level form definitions. Altering CSS classes and HTML attributes is supported.


That should be enough for designers to customize field presentation (using CSS and unobtrusive javascript) without touching python code.

url https://pypi.org/project/django-widget-tweaks/

Install widget-tweaks

$ pip install django-widget-tweaks

Now add widget_tweaks to your INSTALLED_APPS:

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

To start using, must load the template tag in the template you want to use its functions:

{% load widget_tweaks %}

#views.py
from django.shortcuts import render, redirect
from myapp.models import Member
from myapp.forms import MemberForm

# Create your views here.
def index(request):
    members = Member.objects.all()
    return render(request, 'index.html', { 'members': members })

def add_member(request):
    if request.method == 'POST':
        form = MemberForm(request.POST)
        if form.is_valid():
            Member = form.save()
            return redirect('/')
    else:
        form = MemberForm()
    return render(request, 'add_member.html', { 'form': form })
#models.py
from django.db import models
 
# Create your models here.
class Member(models.Model):
    username = models.CharField(max_length=40)
    firstname = models.CharField(max_length=40)
    lastname = models.CharField(max_length=40)
    email = models.EmailField(max_length=254)
    bio = models.TextField(max_length=500)
    created = models.DateTimeField(auto_now_add=True)
  
    def __str__(self):
        return self.firstname + " " + self.lastname
 
    class Meta:
        ordering = ['created']
   
    class Meta:  
        db_table = "blog_member"
#forms.py
from django import forms
from myapp.models import Member
 
class MemberForm(forms.ModelForm):
    class Meta:
        model = Member
        fields = ('username', 'firstname', 'lastname', 'email', 'bio',)
#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', 
]
#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('add_member/',views.add_member),
]
//templates/index.html
{% extends 'base.html' %}

{% block content %}

  <h2>
    Member
    <a href="/add_member" class="btn btn-primary pull-right">
      <span class="glyphicon glyphicon-plus"></span> Add Member
    </a>
  </h2>

  <table class="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>First name</th>
        <th>Last name</th>
        <th>Email</th>
        <th>Phone</th>
        <th>Bio</th>
      </tr>
    </thead>
    <tbody>
      {% for rs in members %}
        <tr>
          <td>{{ rs.id }}</td>
          <td>{{ rs.username }}</td>
          <td>{{ rs.firstname }}</td>
          <td>{{ rs.lastname }}</td>
          <td>{{ rs.email }}</td>
          <td>{{ rs.bio }}</td>
        </tr>
      {% empty %}
        <tr>
          <td colspan="6" class="text-center">No result</td>
        </tr>
      {% endfor %}
    </tbody>
  </table>

{% 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 %}Simple Forms{% 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">Python Django Simple Forms Using Widget Tweaks</h3>
        <hr style="border-top:1px dotted #ccc;"/>
        {% block content %}
 
        {% endblock %}
    </div>
    </div>
</body>
</html>
//templates/add_member.html
{% extends 'base.html' %}

{% load widget_tweaks %}

{% block content %}
  <h2>Add Member</h2>
  <form method="post">
    {% csrf_token %}

    {% for hidden in form.hidden_fields %}
      {{ hidden }}
    {% endfor %}

    {% for field in form.visible_fields %}
      <div class="form-group">
        <label for="{{ field.id_for_label }}">{{ field.label }}</label>
        {% render_field field class="form-control" %}
        {% for error in field.errors %}
          <span class="help-block">{{ error }}</span>
        {% endfor %}
      </div>
    {% endfor %}

    <div class="form-group">
      <button type="submit" class="btn btn-success">
        <span class="glyphicon glyphicon-ok"></span> Save
      </button>
      <a href="/" class="btn btn-default">Cancel</a>
    </div>
  </form>
{% endblock %}

Related Post