
- Python - Home
- Python - Overview
- Python - History
- Python - Features
- Python vs C++
- Python - Hello World Program
- Python - Application Areas
- Python - Interpreter
- Python - Environment Setup
- Python - Virtual Environment
- Python - Basic Syntax
- Python - Variables
- Python - Data Types
- Python - Type Casting
- Python - Unicode System
- Python - Literals
- Python - Operators
- Python - Arithmetic Operators
- Python - Comparison Operators
- Python - Assignment Operators
- Python - Logical Operators
- Python - Bitwise Operators
- Python - Membership Operators
- Python - Identity Operators
- Python - Operator Precedence
- Python - Comments
- Python - User Input
- Python - Numbers
- Python - Booleans
- Python - Control Flow
- Python - Decision Making
- Python - If Statement
- Python - If else
- Python - Nested If
- Python - Match-Case Statement
- Python - Loops
- Python - for Loops
- Python - for-else Loops
- Python - While Loops
- Python - break Statement
- Python - continue Statement
- Python - pass Statement
- Python - Nested Loops
- Python Functions & Modules
- Python - Functions
- Python - Default Arguments
- Python - Keyword Arguments
- Python - Keyword-Only Arguments
- Python - Positional Arguments
- Python - Positional-Only Arguments
- Python - Arbitrary Arguments
- Python - Variables Scope
- Python - Function Annotations
- Python - Modules
- Python - Built in Functions
- Python Strings
- Python - Strings
- Python - Slicing Strings
- Python - Modify Strings
- Python - String Concatenation
- Python - String Formatting
- Python - Escape Characters
- Python - String Methods
- Python - String Exercises
- Python Lists
- Python - Lists
- Python - Access List Items
- Python - Change List Items
- Python - Add List Items
- Python - Remove List Items
- Python - Loop Lists
- Python - List Comprehension
- Python - Sort Lists
- Python - Copy Lists
- Python - Join Lists
- Python - List Methods
- Python - List Exercises
- Python Tuples
- Python - Tuples
- Python - Access Tuple Items
- Python - Update Tuples
- Python - Unpack Tuples
- Python - Loop Tuples
- Python - Join Tuples
- Python - Tuple Methods
- Python - Tuple Exercises
- Python Sets
- Python - Sets
- Python - Access Set Items
- Python - Add Set Items
- Python - Remove Set Items
- Python - Loop Sets
- Python - Join Sets
- Python - Copy Sets
- Python - Set Operators
- Python - Set Methods
- Python - Set Exercises
- Python Dictionaries
- Python - Dictionaries
- Python - Access Dictionary Items
- Python - Change Dictionary Items
- Python - Add Dictionary Items
- Python - Remove Dictionary Items
- Python - Dictionary View Objects
- Python - Loop Dictionaries
- Python - Copy Dictionaries
- Python - Nested Dictionaries
- Python - Dictionary Methods
- Python - Dictionary Exercises
- Python Arrays
- Python - Arrays
- Python - Access Array Items
- Python - Add Array Items
- Python - Remove Array Items
- Python - Loop Arrays
- Python - Copy Arrays
- Python - Reverse Arrays
- Python - Sort Arrays
- Python - Join Arrays
- Python - Array Methods
- Python - Array Exercises
- Python File Handling
- Python - File Handling
- Python - Write to File
- Python - Read Files
- Python - Renaming and Deleting Files
- Python - Directories
- Python - File Methods
- Python - OS File/Directory Methods
- Python - OS Path Methods
- Object Oriented Programming
- Python - OOPs Concepts
- Python - Classes & Objects
- Python - Class Attributes
- Python - Class Methods
- Python - Static Methods
- Python - Constructors
- Python - Access Modifiers
- Python - Inheritance
- Python - Polymorphism
- Python - Method Overriding
- Python - Method Overloading
- Python - Dynamic Binding
- Python - Dynamic Typing
- Python - Abstraction
- Python - Encapsulation
- Python - Interfaces
- Python - Packages
- Python - Inner Classes
- Python - Anonymous Class and Objects
- Python - Singleton Class
- Python - Wrapper Classes
- Python - Enums
- Python - Reflection
- Python Errors & Exceptions
- Python - Syntax Errors
- Python - Exceptions
- Python - try-except Block
- Python - try-finally Block
- Python - Raising Exceptions
- Python - Exception Chaining
- Python - Nested try Block
- Python - User-defined Exception
- Python - Logging
- Python - Assertions
- Python - Built-in Exceptions
- Python Multithreading
- Python - Multithreading
- Python - Thread Life Cycle
- Python - Creating a Thread
- Python - Starting a Thread
- Python - Joining Threads
- Python - Naming Thread
- Python - Thread Scheduling
- Python - Thread Pools
- Python - Main Thread
- Python - Thread Priority
- Python - Daemon Threads
- Python - Synchronizing Threads
- Python Synchronization
- Python - Inter-thread Communication
- Python - Thread Deadlock
- Python - Interrupting a Thread
- Python Networking
- Python - Networking
- Python - Socket Programming
- Python - URL Processing
- Python - Generics
- Python Libraries
- NumPy Tutorial
- Pandas Tutorial
- SciPy Tutorial
- Matplotlib Tutorial
- Django Tutorial
- OpenCV Tutorial
- Python Miscellenous
- Python - Date & Time
- Python - Maths
- Python - Iterators
- Python - Generators
- Python - Closures
- Python - Decorators
- Python - Recursion
- Python - Reg Expressions
- Python - PIP
- Python - Database Access
- Python - Weak References
- Python - Serialization
- Python - Templating
- Python - Output Formatting
- Python - Performance Measurement
- Python - Data Compression
- Python - CGI Programming
- Python - XML Processing
- Python - GUI Programming
- Python - Command-Line Arguments
- Python - Docstrings
- Python - JSON
- Python - Sending Email
- Python - Further Extensions
- Python - Tools/Utilities
- Python - GUIs
- Python Advanced Concepts
- Python - Abstract Base Classes
- Python - Custom Exceptions
- Python - Higher Order Functions
- Python - Object Internals
- Python - Memory Management
- Python - Metaclasses
- Python - Metaprogramming with Metaclasses
- Python - Mocking and Stubbing
- Python - Monkey Patching
- Python - Signal Handling
- Python - Type Hints
- Python - Automation Tutorial
- Python - Humanize Package
- Python - Context Managers
- Python - Coroutines
- Python - Descriptors
- Python - Diagnosing and Fixing Memory Leaks
- Python - Immutable Data Structures
- Python Useful Resources
- Python - Questions & Answers
- Python - Interview Questions & Answers
- Python - Online Quiz
- Python - Quick Guide
- Python - Reference
- Python - Cheatsheet
- Python - Projects
- Python - Useful Resources
- Python - Discussion
- Python Compiler
- NumPy Compiler
- Matplotlib Compiler
- SciPy Compiler
Python - Simple WishList App Using Django
This Django-based web application enables users to view and manage items, mark them as favorites, and interact with their wishlist. In this tutorial, you'll know how to set up and run the wishlist application, as well as detailed explanations of the project structure and code.
Installations
1) First you need it install this library
pip install Django==2.2.13,pip install pytz==2018.9, pip install Pillow
2) Create a New Django Project
django-admin startproject wishlist_api
3) Navigate into the project directory
cd wishlist_api
4) Create a New Django App
python manage.py startapp items
Set Up Project Configurations
Edit the settings.py file in wishlist_api/wishlist_api/ to add the items app to the INSTALLED_APPS list.
Configure Static and Media Files
Update settings.py to configure static and media file settings −
- Static files URL − /static/
- Media files URL and root − /media/ and os.path.join(BASE_DIR, 'media')
Configure URL Routing
Update the urls.py file in wishlist_api/wishlist_api/ to include routes for the items app and media files.
Create the Templates
Create the following templates in the items/templates/ directory −
- base.html − The base layout template.
- home.html − The homepage template.
- item_detail.html − Template for displaying item details.
- item_list.html − Template for listing items.
- navbar.html − Navigation bar template.
- user_login.html − Template for user login.
- user_register.html − Template for user registration.
- wishlist.html − Template for displaying the wishlist.
Set Up Models and Views
1. Define Models
Edit models.py in the items directory to define your data models, such as Item and FavoriteItem.
2. Create Views
Update views.py in the items directory to handle various application views −
- home − Displays the homepage.
- item_list − Lists all items.
- item_detail − Shows details for a specific item.
- user_register − Handles user registration.
- user_login − Manages user login.
- user_logout − Handles user logout.
- item_favorite − Manages item favorite status.
- wishlist − Displays the user's wishlist
First Structure


Code Files for Simple WishList App Using Django
Settings.py
import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', 'your-default-secret-key') DEBUG = os.getenv('DJANGO_DEBUG', 'True') == 'True' ALLOWED_HOSTS = ['yourdomain.com', 'localhost', '127.0.0.1'] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'items', # Add additional apps here ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'wishlist_api.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # Ensure this line is present 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'wishlist_api.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True STATIC_URL = '/static/' MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Urls.py
# wishlist_api/urls.py from django.contrib import admin from django.urls import path from items import views from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('', views.home, name='home'), # Add this line path('admin/', admin.site.urls), path('items/list/', views.item_list, name='item-list'), path('items/detail/<int:item_id>/', views.item_detail, name='item-detail'), path('items/wishlist/', views.wishlist, name='wishlist'), path('user/register/', views.user_register, name='user-register'), path('user/login/', views.user_login, name='user-login'), path('user/logout/', views.user_logout, name='user-logout'), path('items/<int:item_id>/favorite/', views.item_favorite, name='item-favorite'), ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
wsgi.py
""" WSGI config for wishlist_api project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/ """ import os from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "wishlist_api.settings") application = get_wsgi_application()
views.py
from django.shortcuts import render, redirect from items.models import Item, FavoriteItem from .forms import UserRegisterForm, UserLoginForm from django.contrib.auth import login, logout, authenticate from django.http import JsonResponse def home(request): return render(request, 'home.html') def item_list(request): items = Item.objects.all() query = request.GET.get('q') if query: items = items.filter(name__icontains=query) favorite_list = [] if request.user.is_authenticated: favorite_list = request.user.favoriteitem_set.values_list('item', flat=True) context = { "items": items, "favorite_list": favorite_list } return render(request, 'item_list.html', context) def item_detail(request, item_id): context = { "item": Item.objects.get(id=item_id) } return render(request, 'item_detail.html', context) def user_register(request): register_form = UserRegisterForm() if request.method == "POST": register_form = UserRegisterForm(request.POST) if register_form.is_valid(): user = register_form.save(commit=False) user.set_password(register_form.cleaned_data['password']) user.save() login(request, user) return redirect('item-list') context = { "register_form": register_form } return render(request, 'user_register.html', context) def user_login(request): login_form = UserLoginForm() if request.method == "POST": login_form = UserLoginForm(request.POST) if login_form.is_valid(): username = login_form.cleaned_data['username'] password = login_form.cleaned_data['password'] authenticated_user = authenticate(username=username, password=password) if authenticated_user: login(request, authenticated_user) return redirect('item-list') context = { "login_form": login_form } return render(request, 'user_login.html', context) def user_logout(request): logout(request) return redirect('item-list') def item_favorite(request, item_id): if request.user.is_anonymous: return redirect('user-login') item_object = Item.objects.get(id=item_id) favorite, created = FavoriteItem.objects.get_or_create(user=request.user, item=item_object) if created: action = "favorite" else: favorite.delete() action = "unfavorite" response = { "action": action, } return JsonResponse(response, safe=False) def wishlist(request): items = Item.objects.all() query = request.GET.get('q') if query: items = items.filter(name__icontains=query) favorite_objects = [] if request.user.is_authenticated: favorite_objects = request.user.favoriteitem_set.all() wishlist = [item for item in items if any(item.id == fav.item_id for fav in favorite_objects)] context = { "wishlist": wishlist } return render(request, 'wishlist.html', context)
tests.py
from django.test import TestCase from django.urls import reverse from django.contrib.auth.models import User from rest_framework.test import APITestCase from rest_framework import status from datetime import date from items.models import Item, FavoriteItem class ItemListViewTest(APITestCase): def setUp(self): user = User.objects.create_user(username="laila", password="1234567890-=") self.item1 = {'image': 'foo.jpg', 'name': "yaaay", 'description': "yay object", 'added_by': user} self.item2 = {'image': 'foo.jpg', 'name':"booo" , 'description': "boo object", 'added_by': user} Item.objects.create(**self.item1) Item.objects.create(**self.item2) def test_url_works(self): response = self.client.get(reverse('api-list')) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_list(self): response = self.client.get(reverse('api-list')) items = Item.objects.all() self.assertEqual(len(response.data), items.count()) for index, item in enumerate(items): item = items[index] self.assertEqual(dict(response.data[index])['name'], item.name) def test_search(self): response = self.client.get(reverse('api-list'), {'search': 'y'}) items = Item.objects.filter(name__icontains="y") self.assertEqual(len(response.data), items.count()) for index, item in enumerate(items): item = items[index] self.assertEqual(dict(response.data[index])['name'], item.name) def test_ordering(self): response = self.client.get(reverse('api-list'), {'ordering': 'name'}) items = Item.objects.order_by("name") self.assertEqual(len(response.data), items.count()) for index, item in enumerate(items): item = items[index] self.assertEqual(dict(response.data[index])['name'], item.name) def test_details_url(self): response = self.client.get(reverse('api-list')) items = Item.objects.all() self.assertEqual(len(response.data), items.count()) for index, item in enumerate(items): item = items[index] self.assertTrue(reverse('api-detail', args=[item.id]) in dict(response.data[index])['detail']) def test_user_serailized(self): response = self.client.get(reverse('api-list')) items = Item.objects.all() for index, item in enumerate(items): item = items[index] self.assertEqual(dict(response.data[index])['added_by'], {"first_name": item.added_by.first_name, "last_name": item.added_by.last_name}) def test_favourited_field(self): response = self.client.get(reverse('api-list')) items = Item.objects.all() for index, item in enumerate(items): item = items[index] count = FavoriteItem.objects.filter(item=item).count() self.assertEqual(dict(response.data[index])['favourited'], count) class ItemDetailViewTest(APITestCase): def setUp(self): user1 = User.objects.create_user(username="laila", password="1234567890-=") user2 = User.objects.create_user(username="laila2", password="1234567890-=") self.item1 = {'image': 'foo.jpg', 'name': "yaaay", 'description': "yay object", 'added_by': user1} self.item2 = {'image': 'foo.jpg', 'name':"booo" , 'description': "boo object", 'added_by': user2} Item.objects.create(**self.item1) Item.objects.create(**self.item2) def test_url_authorized(self): response = self.client.post(reverse('api-login'), {"username" : "laila", "password": "1234567890-="}) self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + response.data['access']) response = self.client.get(reverse('api-detail', args=[1])) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_url_unauthorized(self): response = self.client.post(reverse('api-login'), {"username" : "laila2", "password": "1234567890-="}) self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + response.data['access']) response = self.client.get(reverse('api-detail', args=[1])) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_details(self): response = self.client.post(reverse('api-login'), {"username" : "laila", "password": "1234567890-="}) self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + response.data['access']) response = self.client.get(reverse('api-detail', args=[1])) self.assertEqual(dict(response.data)['name'], self.item1['name']) def test_users_sent(self): response = self.client.post(reverse('api-login'), {"username" : "laila", "password": "1234567890-="}) self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + response.data['access']) response = self.client.get(reverse('api-detail', args=[1])) people_count = FavoriteItem.objects.filter(item_id=1).count() self.assertEqual(len(dict(response.data)['favourited_by']), people_count)
models.py
from django.db import models from django.contrib.auth.models import User class Item(models.Model): image = models.ImageField() name = models.CharField(max_length=120) description = models.TextField(max_length=255) def __str__(self): return self.name class FavoriteItem(models.Model): item = models.ForeignKey(Item, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
froms.py
from django import forms from django.contrib.auth.models import User class UserRegisterForm(forms.ModelForm): password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'})) class Meta: model = User fields = ['username', 'first_name', 'last_name', 'password'] class UserLoginForm(forms.Form): username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username'})) password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
apps.py
from django.apps import AppConfig class ItemsConfig(AppConfig): name = 'items'
admin.py
from django.contrib import admin from .models import Item # Register your models here. admin.site.register(Item)
Templates html file
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"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.10/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" crossorigin="anonymous"> <title>Items</title> </head> <body> {%include 'navbar.html' %} <br> <div class="container"> {% block content %} {% endblock content %} </div> <script src="http://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script> </body> </html>
home.html
<!-- items/templates/home.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Home</title> </head> <body> <h1>Welcome to the Items App!</h1> <a href="{% url 'item-list' %}">View Items</a> </body> </html>
Item_detail.html
{% extends 'base.html' %} {% block content %} <div class="card mb-3"> <img class="card-img-top" height="700" src="{{item.image.url}}" alt="Card image cap"> <div class="card-body"> <h5 class="card-title">{{item.name}}</h5> <p class="card-text">{{item.description}}</p> </div> </div> {% endblock %}
Item_list.html
{% extends 'base.html' %} {% block content %} <form class="form-inline my-2 my-lg-0" action="{% url 'item-list' %}"> <input class="form-control mr-sm-2" type="search" placeholder="Search Items" aria-label="Search" name="q"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> <div class="row"> {% for item in items %} <div class="col-sm-4 py-2"> <div class="card h-100"> <img class="card-img-top" height="55%" src="{{item.image.url}}" alt="Card image cap"> <div class="card-body bg-light"> <h3 class="card-title">{{item.name}}</h3> <a href="{% url 'item-detail' item.id %}" class="btn btn-outline-dark">More</a> <button class="btn btn-light" onclick="favorite_item({{item.id}})"><i id="star-{{item.id}}" class="fas fa-star {% if item.id in favorite_list %}text-warning{% endif %}"></i></button> </div> </div> </div> {% endfor %} </div> <script> function favorite_item(id){ $.ajax( { type: "GET", url: "/items/" + id + "/favorite", error: function(){ console.log('error'); }, success: function(data){ console.log(data); var item_id = "#star-"+id; console.log(item_id) if(data.action === "favorite"){ console.log("the action is favorite") $(item_id).addClass("text-warning"); } else { $(item_id).removeClass("text-warning"); } }, } ); } </script> {% endblock%}
Navbar.html
<nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="{% url 'item-list' %}">Items</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> {% if request.user.is_anonymous %} <li class="nav-item"> <a class="nav-link" href="{% url 'user-register' %}">Register</a> </li> <li class="nav-item"> <a class="nav-link" href="{% url 'user-login' %}">Login</a> </li> {% else %} <li class="nav-item"> <a class="nav-link" href="{% url 'wishlist' %}">My Wishlist</></a> </li> <li class="nav-item"> <span class="nav-link disabled" href="#">Welcome, {{request.user}}.</span> </li> <li class="nav-item"> <a class="nav-link" href="{% url 'user-logout' %}">Logout</a> </li> {% endif %} </ul> </div> </nav>
User_login.html
{% extends 'base.html' %} {% block content %} <form action="{% url 'user-login' %}" method="POST"> {% csrf_token %} {{login_form.as_p}} <input type="submit" value="Login"> </form> {% endblock %}
User_register.html
{% extends 'base.html' %} {% block content %} <form action="{% url 'user-register' %}" method="POST"> {% csrf_token %} {{register_form.as_p}} <input type="submit" value="Register"> </form> {% endblock %}
Wishlist.html
{% extends 'base.html' %} {% block content %} <form class="form-inline my-2 my-lg-0" action="{% url 'wishlist' %}"> <input class="form-control mr-sm-2" type="search" placeholder="Search Items" aria-label="Search" name="q"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> <div class="row"> {% for item in wishlist %} <div class="col-sm-4 py-2"> <div class="card h-100"> <img class="card-img-top" height="55%" src="{{item.image.url}}" alt="Card image cap"> <div class="card-body bg-light"> <h3 class="card-title">{{item.name}}</h3> <a href="{% url 'item-detail' item.id %}" class="btn btn-outline-dark">More</a> </div> </div> </div> {% endfor %} </div> {% endblock %}
Media file
In media file we used these images, you can use any images.

Make Migrations
Open your terminal and write this −
python manage.py makemigrations
Apply Migrations
Open your terminal and write this −
python manage.py migrate
Run the Development Server
Write the following command to run the development server −
python manage.py runserver
The application will be available at http://127.0.0.1:8000/.
OUTPUT
After you write python manage.py runserver it will show −

Then copy the server open this incognito mode −

Then search you will see page home page , you need to click view page −

After that you will see wishlist page −

If you click more you will the product description −

If you click register you will see registration page −

Login page −
