0 NewProj
01 将source_data材料包放到项目根目录。将其中的static文件夹剪切到根目录。将剩下的temps文件剪切到templates文件夹下。可删source_data。后续用默认sqlite。
STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')
]
02 python manage.py startapp product。python manage.py startapp users 。python manage.py startapp orders。安装、路由链接。users下temp/usr与login html。
1 users_app (① 登录 退出 ② 登录后登录注册按钮显示为用户名 ③ 点击用户名跳转至用户账户页面)
11 models 迁移
from django.db import modelsclass User(models.Model):user_name = models.CharField(max_length=32, unique=True)password = models.CharField(max_length=128)token = models.CharField(max_length=128, null=True)class Meta:db_table = 'users'@classmethoddef get_list(cls, **kwargs):filters = {} # 赋值等号有空格,传参等号无空格if kwargs.get('user_name'):filters['user_name'] = kwargs.get('user_name')if kwargs.get('password'):filters['password'] = kwargs.get('password')return cls.objects.filter(**filters)@classmethoddef create_one(cls, user_name, password):return cls.objects.create(user_name=user_name, password=password)@classmethoddef get_one(cls, pk):try:return cls.objects.get(pk=pk)except cls.DoesNotExist:return None
12 html调整
<!DOCTYPE html>
{% load static %}
<html lang="zxx">herf ="{% static 'xxx.cssjsjpgpng'%}"<form action="#">
{% csrf_token %}
<div class="login-form">
13 views 类视图
import timefrom django.http import HttpResponse
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import Viewfrom users.models import User
from utils.utils import gen_md5class LoginRegisterView(View):def get(self, request):return render(self.request, 'login_register.html')class RegisterView(View):def post(self, request):user_name = self.request.POST.get('user_name')password = gen_md5(request.POST.get('password'))user = User.get_list(user_name=user_name)if user:return HttpResponse("Occupied user info.")User.create_one(user_name=user_name, password=password)return redirect(reverse("users:login_register"))class LoginView(View):def post(self, request):user_name = self.request.POST.get('user_name')password = gen_md5(request.POST.get('password'))user = User.get_list(user_name=user_name, password=password)if user:user = user.first()user.token = gen_md5(user.user_name) + str(time.time())user.save()self.request.session['user_token'] = user.tokenself.request.session['user_id'] = user.user_idreturn redirect(reverse("users:my_account"))else:return HttpResponse("Wrong Info.")class LogoutView(View):def post(self, request):user_id = request.session.get('user_id')user = User.get_one(pk=user_id)if user:user.token = ""user.save()self.request.session.flush()return redirect(reverse("users:login_register"))class MyAccountView(View):def get(self, request):return render(request, "my_account.html")
14 加密工具。proj/utils.pck/utils.py
import hashlibdef gen_md5(string: str) -> str:md5 = hashlib.md5()md5.update(string.encode('utf-8'))return md5.hexdigest()
15 urls
from django.urls import pathfrom users.views import LoginRegisterView, LoginView, RegisterView, LogoutView, MyAccountViewapp_name = 'users'urlpatterns = [path('login_register/', LoginRegisterView.as_view(), name='login_register'),path('login/', LoginView.as_view(), name='login'),path('register/', RegisterView.as_view(), name='register'),path('logout/', LogoutView.as_view(), name='logout'),path('my_account/', MyAccountView.as_view(), name='my_account'),
]
2 product_app(分页展示;search by category,or name。这里我们假设商品和分类是一对多的关系。)
21 models 注意这里没有完善商品详情。一个oneto'onefield类。迁移
22 views
将图片从admin中上传到前端可static探测到的路径。默认会上传到根目录,需要设置一个media路径。static下new direc product。setting:
STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')
]# MEDIA_URL = os.path.join(BASE_DIR, 'static', 'product') # 不设置upload to
MEDIA_URL = os.path.join(BASE_DIR, 'static', 'product') # 设置upload属性,自动生成文件夹,不需要自己建
23 product model
from django.db import modelsclass Category(models.Model):category_name = models.CharField(max_length=32, verbose_name='category name')class Meta:db_table = 'category'verbose_name = 'category table'verbose_name_plural = verbose_namedef __str__(self):return self.category_name@classmethoddef get_all(cls):return Category.objects.all()class Product(models.Model):product_name = models.CharField(max_length=32, verbose_name='product name')price = models.FloatField(verbose_name='product price')category = models.ForeignKey(Category, on_delete=models.CASCADE)image = models.ImageField(upload_to="product", verbose_name='product image', null=True)class Meta:db_table = 'product'verbose_name = 'product list table'verbose_name_plural = verbose_namedef __str__(self):return self.product_name@classmethoddef get_list(cls, **kwargs):filters = {}if kwargs.get('name'):filters['product_name__contains'] = kwargs.get('name')if kwargs.get('category'): # obj 一方查多方filters['category'] = kwargs.get('category')return cls.objects.filter(**filters)@classmethoddef get_one(cls, pk):try:return cls.objects.get(pk=pk)except cls.DoesNotExist:return None
admin
from django.contrib import adminfrom product.models import Product, Categoryadmin.site.register([Product, Category,
])
24 views
from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage
from django.shortcuts import render
from django.views import Viewfrom djangoProject1.settings import PAGE_SIZE
from product.models import Product, Categoryfrom users.models import Userclass ProductListView(View):def get(self, request):page_num = self.request.GET.get('page', 1)filters = {'category': self.request.GET.get('category', ""),'name': self.request.GET.get('name', "")}category = Category.get_all()user = ""user_id = self.request.session.get("user_id")if user_id:user_obj = User.get_one(pk=user_id)if user_obj:user = user_obj # {% if user %}前端作判断用products = Product.get_list(**filters)products_data = []for product in products:products_data.append({'product_name': product.product.name,'price': product.price,'category': product.category.category_name,'image': f"product/{product.image}"}) # 用于分页后前端点语法展示属性paginator = Paginator(products_data, PAGE_SIZE)try:data = paginator.page(page_num)except InvalidPage:data = paginator.page(1)return render(self.request, "shop.html")class ProductDetailView(View):def get(self, request, product_id):product = Product.get_one(pk=product_id)product = {'product_name': product.product.name,'price': product.price,'category': product.category.category_name,'image': f"product/{product.image}"}return render(self.request, 'single_product.html', locals())
25 urls
from django.urls import pathfrom product.views import ProductListView, ProductDetailViewapp_name = 'product'urlpatterns = [path('list/', ProductListView.as_view(), name='list'),path('detail/<int:product_id>/', ProductDetailView.as_view(), name='detail')
]
3 orders_app (展示预订单内容;成交后清空)
31 models
from django.db import modelsfrom product.models import Product
from users.models import Userclass Orders(models.Model):product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="product")quantity = models.IntegerField(verbose_name='Quantity')status = models.IntegerField(default=0, verbose_name='Order Status') # 支付否user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="user")order_id = models.CharField(max_length=32, verbose_name='Order ID', null=True)class Meta:db_table = 'orders'@classmethoddef get_one(cls, pk):try:return cls.objects.get(pk=pk)except cls.DoesNotExist:return None@classmethoddef get_list(cls, **kwargs):filters = {}if kwargs.get('user'):filters['user'] = kwargs.get('user')if kwargs.get('status') or kwargs.get('status') == 0:filters['status'] = kwargs.get('status')return cls.objects.filter(**filters)@classmethoddef create_one(cls, product, quantity, user):return cls.objects.create(product=product,quantity=quantity,user=user)@classmethoddef batch_update(cls, ids, order_id):for item_id in ids:obj = cls.get_one(item_id)obj.order_id = order_idobj.status = 1obj.save()
32 views
import timefrom django.http import HttpResponseRedirect, HttpResponse, JsonResponse
from django.shortcuts import render
from django.views import Viewfrom orders.models import Orders
from product.models import Product
from users.models import Userclass OrderDetailView(View):def get(self, request):user_id = self.request.session.get('user_id')if not user_id:return HttpResponse('Not logged in.')user = User.get_one(user_id)orders = Orders.get_list(user=user, status=0)price_list = []order_data = []for order in orders:price_list.append(order.product.price * order.quantity)order_data.append({"product_image": f"{order.product.image}","product_name": order.product.product_name,"product_price": order.product.price,"quantity": order.quantity,"sum": order.quantity * order.product.price})total = sum(price_list)return render(self.request, 'order_detail.html', locals())class OrderAddView(View):def post(self, request):product_id = self.request.POST.get('product_id')product = Product.objects.get(id=product_id)quantity = self.request.POST.get('quantity')user_id = request.session.get('user_id')user = User.get_one(user_id)Orders.create_one(product, quantity, user)return HttpResponse('Added.')class OrderBuyView(View):def post(self, request):ids = list(map(int, self.request.session.get('ids')))order_id = f"Order{time.time()}"Orders.batch_update(ids, order_id)return HttpResponse('Done.')class OrderListView(View):def get(self, request):user_id = self.request.session.get('user_id')user = User.get_one(user_id)orders = Orders.get_list(user=user, status=0)order_data = []prince_list = []for order in orders:prince_list.append(order.product.price * order.quantity)order_data.append({"image": f"product/{order.product.image}","name": order.product.product_name,"price": order.product.price,"quantity": order.quantity,"sum": order.quantity * order.product.price})total = sum(prince_list)return JsonResponse(order_data)
33 urls
from django.urls import pathfrom orders.views import OrderDetailView, OrderBuyView, OrderAddViewapp_name = 'orders'urlpatterns = [path('detail/<order_id>/', OrderDetailView.as_view(), name='detail'),path('buy/', OrderBuyView.as_view(), name='buy'),path('add/', OrderAddView.as_view(), name='add'),
]