开发实践10_PurchaseOrder笔记

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 models


class 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'

    @classmethod
    def 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)

    @classmethod
    def create_one(cls, user_name, password):
        return cls.objects.create(user_name=user_name, password=password)

    @classmethod
    def 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 time

from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View

from users.models import User
from utils.utils import gen_md5


class 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.token
            self.request.session['user_id'] = user.user_id
            return 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 hashlib


def gen_md5(string: str) -> str:
    md5 = hashlib.md5()
    md5.update(string.encode('utf-8'))
    return md5.hexdigest()

15 urls

复制代码
from django.urls import path

from users.views import LoginRegisterView, LoginView, RegisterView, LogoutView, MyAccountView

app_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 models


class 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_name

    def __str__(self):
        return self.category_name

    @classmethod
    def 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_name

    def __str__(self):
        return self.product_name

    @classmethod
    def 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)

    @classmethod
    def get_one(cls, pk):
        try:
            return cls.objects.get(pk=pk)
        except cls.DoesNotExist:
            return None

admin

复制代码
from django.contrib import admin

from product.models import Product, Category

admin.site.register([
    Product, Category,
])

24 views

复制代码
from django.core.paginator import Paginator, PageNotAnInteger, InvalidPage
from django.shortcuts import render
from django.views import View

from djangoProject1.settings import PAGE_SIZE
from product.models import Product, Category

from users.models import User


class 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 path

from product.views import ProductListView, ProductDetailView

app_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 models

from product.models import Product
from users.models import User


class 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'

    @classmethod
    def get_one(cls, pk):
        try:
            return cls.objects.get(pk=pk)
        except cls.DoesNotExist:
            return None

    @classmethod
    def 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)

    @classmethod
    def create_one(cls, product, quantity, user):
        return cls.objects.create(
            product=product,
            quantity=quantity,
            user=user
        )

    @classmethod
    def batch_update(cls, ids, order_id):
        for item_id in ids:
            obj = cls.get_one(item_id)
            obj.order_id = order_id
            obj.status = 1
            obj.save()

32 views

复制代码
import time

from django.http import HttpResponseRedirect, HttpResponse, JsonResponse
from django.shortcuts import render
from django.views import View

from orders.models import Orders
from product.models import Product
from users.models import User


class 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 path

from orders.views import OrderDetailView, OrderBuyView, OrderAddView

app_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'),
]
相关推荐
马可家的菠萝13 小时前
你收藏的资料,有多少真的被你第二次打开过?
笔记·知识管理·效率提升·个人知识库
小刘在重生~14 小时前
Java Lock 显式锁案例|ReentrantLock 解决多线程安全问题(超详细实战)
java·笔记·面试
职豚求职小程序14 小时前
中国人寿27秋招笔试[特殊字符]北森机考|备考攻略
笔记
江湖人称菠萝包14 小时前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter9-Qt Charts
笔记·qt·qt5
乐橙开放平台14 小时前
从「多套客户端」到一套开放能力:乐橙视频监控能力复盘
笔记·物联网·自动化·音视频·智能家居
山岚的运维笔记15 小时前
mysql 专业笔记 -- 第 36 章:MySQL 管理
运维·数据库·笔记·后端·mysql·oracle·dba
江湖人称菠萝包17 小时前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter10-Data Visualization
笔记·qt·qt5
老当益壮梁奶奶18 小时前
ARM汇编学习笔记(五):从按键轮询到 GIC 中断控制器(ARM Cortex-A7 )
arm开发·笔记·单片机·嵌入式硬件
既然如此,那就开摆18 小时前
2023_Kirillov_SAM_总结
笔记·学习·遥感
志尊宝18 小时前
Vue3 零基础每日笔记(048):嵌套路由与命名视图——后台管理系统布局雏形
前端·javascript·vue.js·笔记·html5