- Python基礎
- Python - 首頁
- Python - 概述
- Python - 歷史
- Python - 特性
- Python vs C++
- Python - Hello World程式
- Python - 應用領域
- Python - 直譯器
- Python - 環境搭建
- Python - 虛擬環境
- Python - 基本語法
- Python - 變數
- Python - 資料型別
- Python - 型別轉換
- Python - Unicode系統
- Python - 字面量
- Python - 運算子
- Python - 算術運算子
- Python - 比較運算子
- Python - 賦值運算子
- Python - 邏輯運算子
- Python - 位運算子
- Python - 成員運算子
- Python - 身份運算子
- Python - 運算子優先順序
- Python - 註釋
- Python - 使用者輸入
- Python - 數字
- Python - 布林值
- Python控制語句
- Python - 控制流
- Python - 決策
- Python - if語句
- Python - if else
- Python - 巢狀if
- Python - Match-Case語句
- Python - 迴圈
- Python - for迴圈
- Python - for-else迴圈
- Python - while迴圈
- Python - break語句
- Python - continue語句
- Python - pass語句
- Python - 巢狀迴圈
- Python函式與模組
- Python - 函式
- Python - 預設引數
- Python - 關鍵字引數
- Python - 僅關鍵字引數
- Python - 位置引數
- Python - 僅位置引數
- Python - 可變引數
- Python - 變數作用域
- Python - 函式註解
- Python - 模組
- Python - 內建函式
- Python字串
- Python - 字串
- Python - 字串切片
- Python - 修改字串
- Python - 字串連線
- Python - 字串格式化
- Python - 跳脫字元
- Python - 字串方法
- Python - 字串練習
- Python列表
- Python - 列表
- Python - 訪問列表元素
- Python - 修改列表元素
- Python - 新增列表元素
- Python - 刪除列表元素
- Python - 遍歷列表
- Python - 列表推導式
- Python - 排序列表
- Python - 複製列表
- Python - 合併列表
- Python - 列表方法
- Python - 列表練習
- Python元組
- Python - 元組
- Python - 訪問元組元素
- Python - 更新元組
- Python - 解包元組
- Python - 遍歷元組
- Python - 合併元組
- Python - 元組方法
- Python - 元組練習
- Python集合
- Python - 集合
- Python - 訪問集合元素
- Python - 新增集合元素
- Python - 刪除集合元素
- Python - 遍歷集合
- Python - 合併集合
- Python - 複製集合
- Python - 集合運算子
- Python - 集合方法
- Python - 集合練習
- Python字典
- Python - 字典
- Python - 訪問字典元素
- Python - 修改字典元素
- Python - 新增字典元素
- Python - 刪除字典元素
- Python - 字典檢視物件
- Python - 遍歷字典
- Python - 複製字典
- Python - 巢狀字典
- Python - 字典方法
- Python - 字典練習
- Python陣列
- Python - 陣列
- Python - 訪問陣列元素
- Python - 新增陣列元素
- Python - 刪除陣列元素
- Python - 遍歷陣列
- Python - 複製陣列
- Python - 反轉陣列
- Python - 排序陣列
- Python - 合併陣列
- Python - 陣列方法
- Python - 陣列練習
- Python檔案處理
- Python - 檔案處理
- Python - 寫入檔案
- Python - 讀取檔案
- Python - 重新命名和刪除檔案
- Python - 目錄
- Python - 檔案方法
- Python - OS檔案/目錄方法
- Python - OS路徑方法
- 面向物件程式設計
- Python - OOPs概念
- Python - 類與物件
- Python - 類屬性
- Python - 類方法
- Python - 靜態方法
- Python - 建構函式
- Python - 訪問修飾符
- Python - 繼承
- Python - 多型
- Python - 方法重寫
- Python - 方法過載
- Python - 動態繫結
- Python - 動態型別
- Python - 抽象
- Python - 封裝
- Python - 介面
- Python - 包
- Python - 內部類
- Python - 匿名類和物件
- Python - 單例類
- Python - 包裝類
- Python - 列舉
- Python - 反射
- Python錯誤與異常
- Python - 語法錯誤
- Python - 異常
- Python - try-except塊
- Python - try-finally塊
- Python - 丟擲異常
- Python - 異常鏈
- Python - 巢狀try塊
- Python - 使用者自定義異常
- Python - 日誌記錄
- Python - 斷言
- Python - 內建異常
- Python多執行緒
- Python - 多執行緒
- Python - 執行緒生命週期
- Python - 建立執行緒
- Python - 啟動執行緒
- Python - 執行緒連線
- Python - 執行緒命名
- Python - 執行緒排程
- Python - 執行緒池
- Python - 主執行緒
- Python - 執行緒優先順序
- Python - 守護執行緒
- Python - 執行緒同步
- Python同步
- Python - 執行緒間通訊
- Python - 執行緒死鎖
- Python - 中斷執行緒
- Python網路程式設計
- Python - 網路程式設計
- Python - Socket程式設計
- Python - URL處理
- Python - 泛型
- Python庫
- NumPy教程
- Pandas教程
- SciPy教程
- Matplotlib教程
- Django教程
- OpenCV教程
- Python雜項
- Python - 日期與時間
- Python - 數學
- Python - 迭代器
- Python - 生成器
- Python - 閉包
- Python - 裝飾器
- Python - 遞迴
- Python - 正則表示式
- Python - PIP
- Python - 資料庫訪問
- Python - 弱引用
- Python - 序列化
- Python - 模板
- Python - 輸出格式化
- Python - 效能測量
- Python - 資料壓縮
- Python - CGI程式設計
- Python - XML處理
- Python - GUI程式設計
- Python - 命令列引數
- Python - 文件字串
- Python - JSON
- Python - 傳送郵件
- Python - 擴充套件
- Python - 工具/實用程式
- Python - GUIs
- Python高階概念
- Python - 抽象基類
- Python - 自定義異常
- Python - 高階函式
- Python - 物件內部
- Python - 記憶體管理
- Python - 元類
- Python - 使用元類的超程式設計
- Python - 模擬和存根
- Python - Monkey Patching
- Python - 訊號處理
- Python - 型別提示
- Python - 自動化教程
- Python - Humanize包
- Python - 上下文管理器
- Python - 協程
- Python - 描述符
- Python - 診斷和修復記憶體洩漏
- Python - 不可變資料結構
- Python實用資源
- Python - 問答
- Python - 線上測驗
- Python - 快速指南
- Python - 參考
- Python - 速查表
- Python - 專案
- Python - 實用資源
- Python - 討論
- Python編譯器
- NumPy編譯器
- Matplotlib編譯器
- SciPy編譯器
Python - 基於Django的簡單願望清單應用
這個基於Django的Web應用程式允許使用者檢視和管理商品,將商品標記為收藏,並與他們的願望清單互動。在本教程中,您將學習如何設定和執行願望清單應用程式,以及專案結構和程式碼的詳細解釋。
安裝
1) 首先你需要安裝這個庫
pip install Django==2.2.13,pip install pytz==2018.9, pip install Pillow
2) 建立一個新的Django專案
django-admin startproject wishlist_api
3) 導航到專案目錄
cd wishlist_api
4) 建立一個新的Django應用
python manage.py startapp items
設定專案配置
編輯**wishlist_api/wishlist_api/**中的**settings.py**檔案,將items應用新增到**INSTALLED_APPS**列表中。
配置靜態檔案和媒體檔案
更新**settings.py**以配置靜態檔案和媒體檔案設定:
- **靜態檔案URL** - /static/
- **媒體檔案URL和根目錄** - /media/ 和 os.path.join(BASE_DIR, 'media')
配置URL路由
更新wishlist_api/wishlist_api/中的urls.py檔案,以包含items應用和媒體檔案的路由。
建立模板
在**items/templates/**目錄下建立以下模板:
- **base.html** - 基本佈局模板。
- **home.html** - 首頁模板。
- **item_detail.html** - 顯示商品詳情的模板。
- **item_list.html** - 列出商品的模板。
- **navbar.html** - 導航欄模板。
- **user_login.html** - 使用者登入模板。
- **user_register.html** - 使用者註冊模板。
- **wishlist.html** - 顯示願望清單的模板。
設定模型和檢視
1. 定義模型
編輯items目錄中的**models.py**檔案以定義你的資料模型,例如**Item**和**FavoriteItem**。
2. 建立檢視
更新items目錄中的views.py檔案以處理各種應用程式檢視:
- **home** - 顯示首頁。
- **item_list** - 列出所有商品。
- **item_detail** - 顯示特定商品的詳細資訊。
- **user_register** - 處理使用者註冊。
- **user_login** - 管理使用者登入。
- **user_logout** - 處理使用者登出。
- **item_favorite** - 管理商品收藏狀態。
- **wishlist** - 顯示使用者的願望清單
初始結構
基於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)
forms.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)
模板html檔案
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" crossorigin="anonymous">
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.0.10/css/all.css"
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"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" 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 %}
媒體檔案
媒體檔案中使用了這些圖片,您可以使用任何圖片。
建立遷移
開啟您的終端並輸入:
python manage.py makemigrations
應用遷移
開啟您的終端並輸入:
python manage.py migrate
執行開發伺服器
輸入以下命令執行開發伺服器:
python manage.py runserver
應用程式將在http://127.0.0.1:8000/訪問。
輸出
輸入python manage.py runserver後,將顯示:
然後複製伺服器地址,在隱身模式下開啟:
然後搜尋,您將看到主頁,您需要點選檢視頁面:
之後您將看到願望清單頁面:
如果您點選更多,您將看到產品描述:
如果您點選註冊,您將看到註冊頁面:
登入頁面:
python_projects_from_basic_to_advanced.htm
廣告