Advanced

Forms and REST API

Handle form submissions securely and build REST APIs with Django REST Framework.

Django Forms

Django's form system handles:

  • HTML form generation
  • Data validation
  • CSRF protection (automatic!)
  • Converting to Python types

ModelForm

ModelForm automatically creates a form based on a model — ideal for create/update operations.

Django REST Framework (DRF)

DRF is the go-to package for building REST APIs with Django. It provides serializers, viewsets, authentication, and more.

bash
pip install djangorestframework

Example

python
# blog/forms.py
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'content', 'excerpt', 'category', 'status']
        widgets = {
            'content': forms.Textarea(attrs={'rows': 10}),
            'excerpt': forms.Textarea(attrs={'rows': 3}),
        }

    def clean_title(self):
        title = self.cleaned_data.get('title', '')
        if len(title) < 5:
            raise forms.ValidationError("Title must be at least 5 characters.")
        return title

# View using the form
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect

@login_required
def create_post(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.save()
            return redirect('post-detail', slug=post.slug)
    else:
        form = PostForm()
    return render(request, 'blog/post_form.html', {'form': form})

# Django REST Framework
from rest_framework import serializers, viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly

class PostSerializer(serializers.ModelSerializer):
    author_name = serializers.CharField(source='author.username', read_only=True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'slug', 'content', 'status', 'author_name', 'created_at']
        read_only_fields = ['slug', 'author_name', 'created_at']

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.filter(status='published')
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)
Try it yourself — PYTHON