Django Blog Forms Favorites
## Forms and Favorites
In this chapter, you will learn to handle user POST requests, establish many-to-many relationships, and implement the "favorite article" feature.
* * *
## Favorite Feature Data Model Design
The core of the favorite feature is: a user can favorite multiple articles, and an article can be favorited by multiple users.
This is a typical many-to-many (ManyToMany) relationship.
We don't need to create a new model β Django's User model is built-in, we just need to add a ManyToManyField pointing to User in the Post model.
## Example
# Add to Post class in blog/models.py
from django.contrib.auth.models import User
class Post(models.Model):
# ... existing fields ...
# Favorites: ManyToManyField automatically creates intermediate table
favorites = models.ManyToManyField(
User,
related_name='favorite_posts',# Reverse query: user.favorite_posts.all()
verbose_name='Favorites',
blank=True
)
After modifying the model, generate and execute migrations:
(venv) $ python manage.py makemigrations (venv) $ python manage.py migrate
* * *
## Favorite and Unfavorite View Logic
## Example
# File path: blog/views.py add new
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .models import Post
# login_required decorator: redirects to login page when unauthenticated users access this view
@login_required
def toggle_favorite(request, pk):
"""Toggle favorite status: favorite β unfavorite, unfavorite β favorite"""
post = get_object_or_404(Post, pk=pk)
# Check if current user has already favorited
if post.favorites.filter(id=request.user.id).exists():
# Already favorited β unfavorite
post.favorites.remove(request.user)
messages.info(request, f'Unfavorited "{post.title}"')
else:
# Not favorited β add to favorites
post.favorites.add(request.user)
messages.success(request, f'Favorited "{post.title}"')
# Redirect back to current page (HTTP_REFERER is the source page URL)
referer = request.META.get('HTTP_REFERER','/')
return redirect(referer)
### ManyToMany Operation Methods Quick Reference
| Method | Description | Example |
| --- | --- | --- |
| add(obj) | Add association | `post.favorites.add(user)` |
| remove(obj) | Remove association | `post.favorites.remove(user)` |
| all() | Query all associated objects | `post.favorites.all()` |
| filter(...) | Filter with conditions | `post.favorites.filter(id=1)` |
| exists() | Check if matching records exist | `post.favorites.filter(id=1).exists()` |
| clear() | Clear all associations | `post.favorites.clear()` |
* * *
## Configure Favorite Route
## Example
# File path: blog/urls.py append
urlpatterns =[
# ... existing routes ...
path('post//favorite/', views.toggle_favorite, name='toggle_favorite'),
]
* * *
## Add Favorite Button on Detail Page
## Example
{% extends 'blog/base.html' %}
{% block title %}{{ post.title }} - TUTORIAL Blog{% endblock %}
{% block content %}
{{ post.category.name }}
YouTip