Django初创shop应用

news2024/11/19 2:17:17

创建项目和应用


启动一个名为mysite的新项目,其中包含一个名为shop的应用程序。
打开shell并运行以下命令:
django-admin startproject mysite
cd myshop/
django-admin startapp shop

将shop应用程序添加到INSTALLED_APPS
编辑项目的settings.py文件:

INSTALLED_APPS = [
 # ...
 'shop.apps.ShopConfig',
]

创建应用模型


商店的目录将包括按不同类别分类的产品。
产品信息包括:

  • 类别(category):关联类别
  • 名称(name):最大长度200,开启索引
  • 描述(description):可选
  • 图像(image):可选
  • 价格(price):最大位数10,小数位数2
  • 可用性(available):默认可用
  • 自动生成创建和更新时间

编辑shop应用的models.py文件:

from django.db import models
from django.urls import reverse

class Category(models.Model):
    name = models.CharField(max_length=200,db_index=True)
    slug = models.SlugField(max_length=200,unique=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'category'
        verbose_name_plural = 'categories'
    
    def __str__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('shop:product_list_by_category',args=[self.slug])
    
class Product(models.Model):
    category = models.ForeignKey(Category,related_name='products',on_delete=models.CASCADE)
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True)
    image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10,decimal_places=2)
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('name',)
        index_together = (('id','slug'),)
    
    def __str__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('shop:product_detail',args=[self.id,self.slug])
  • ForeignKey是一对多关系,一个类别对应多个产品。
  • slug讲为这个产品构建URL。
  • decimal.Decimal是固定精度数字,包含两个参数:max_digits设置最大位数(包含小数位),decimal_places设置小数位数。

建议使用DecimalField来存储货币金额。可以避免浮点四舍五入问题。

在Meta中设置的参数含义:

  • ordering:排序。
  • verbose_name:在admin管理界面中显示中文,单数形式显示。
  • verbose_name_plural:复数形式显示,中文单数和复数一半不作区别。

如果需要指定数据库的表名称,可是使用db_table = 'Table name'

因为计划通过id和编号查询产品,在Product模型中,使用了index_together指定id,slug一起被索引,提供使用这两个字段的查询性能。

何时需要使用db_index=True?
频繁查询的字段(产品名字),外键字段(类别),唯一值(ID)。虽然所以可以提高查询性能,但也需要消耗一定的存储空间并导致写入速度变慢。
少查询字段,低基数字段(比如性别,只有男,女两个值),稀疏字段(字段值出现频率过低),都是不建议使用的。

通过django.urls导入reverse()函数,并向Category和Product模型添加get_absolute_url()方法。
get_absolute_url()是检索给定对象的URL的约定。后面,我们将在URLs .py文件中定义的url模式。

image字段需要上传图片。打开shell并运行以下命令:
pip install Pillow

同步模型到数据库
python manage.py makemigrations
python manage.py migrate


注册到管理站点


将模型添加到管理站点,以便使用管理站点轻松地管理类别和产品。
编辑shop应用程序的admin.py文件:

from django.contrib import admin
from .models import Category,Product

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ['name','slug']
    prepopulated_fields = {'slug':('name',)}

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ['name','slug','price','available','created','updated']
    list_filter = ['available','created','updated']
    list_editable = ['price','available']
    prepopulated_fields = {'slug':('name',)}
  • 使用prepopulated_fields使用name的值自动生成slug
  • 使用list_editable设置从管理站点的列表显示页面编辑字段,可以一次编辑多行。

list_editable中的任何字段必须在list_display列表中,只有显示的字段可以编辑

运行python .\manage.py runserver

用浏览器登录管理站点 http://127.0.0.1:8000/admin

产品管理列表如图

构建应用视图


创建一个视图来列出所有产品或按给定类别筛选产品。
编辑shop应用程序的views.py文件:

from django.shortcuts import render,get_object_or_404
from .models import Category,Product

def product_list(request,category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    if category_slug:
        category = get_object_or_404(Category,slug=category_slug)
        print(category.name)
        products = products.filter(category=category)
    
    template = 'shop/product/list.html'
    context = {'category':category,'categories':categories,'products':products}
    return render(request,template,context)


def product_detail(request,id,slug):
    product = get_object_or_404(Product,id=id,slug=slug,available=True)
    template = 'shop/product/detail.html'
    context = {'product':product}
    return render(request,template,context)
  • product_list使用了一个可选的category_slug参数按给定的类别筛选产品。过滤带有available=True的QuerySet,只检索可用的产品。
  • product_detail视图来检索和显示单个产品。需要id和slug参数,以便检索产品实例。我们可以通过ID获得这个实例,因为它是唯一属性。但是,我们在URL中包含了slug,以便为产品构建seo友好的URL。

创建应用URL

在构建了产品列表和详细信息视图之后,需要为它们定义URL模式。
在shop应用目录中创建一个新文件,并将其命名为urls.py。将以下代码添加到其中:

from django.urls import path
from . import views

app_name = 'shop'

urlpatterns = [
    path('',views.product_list,name='product_list'),
    path('<slug:category_slug>',views.product_list,name='product_list_by_category'),
    path('<int:id>/<slug:slug>',views.product_detail,name='product_detail'),
]
  • product_list视图定义了两种不同的URL模式:一个名为product_list的模式,它调用product_list视图而不带任何参数;还有一个名为product_list_by_category的模式,它为视图提供了一个category_slug参数,用于根据给定的类别过滤产品。
  • product_detail视图添加了一个模式,它将id和slug参数传递给视图,以便检索特定的产品。

编辑mysite项目的urls.py文件,使其看起来像这样:

from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
	#...
    path("shop/",include('shop.urls',namespace='shop')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

因为用到了图片上传,使用static配置开发环境的静态文件。

在项目的setting.py中,添加以下代码:

STATIC_URL = "static/"
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

创建应用模版


需要为产品列表和详细信息视图创建模板。
在shop应用程序目录中创建以下目录和文件结构:
templates/shop/base.html
templates/shop/product/list.html
templates/shop/product/detail.html
首先需要定义一个base基本模板,然后在产品列表(list.html)和详细信息模板(detail.html)中扩展它。编辑shop/base.html模板,并添加以下代码:

{% load static %}
<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8" />
 <title>{% block title %}My shop{% endblock %}</title>
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
    <div class="navbar bg-body-tertiary">
        <div class="container-fluid">
            <a class="navbar-brand" href="/shop">My shop</a>
        </div>
    
    </div>
    <div id="subheader">
    <div class="cart">
        <div class="alert alert-light" role="alert">
            Your cart is empty.
        </div>
        
    </div>
    </div>
    <div class="container">
        {% block content %}
        {% endblock %}
    </div>

<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>
</body>
</html>

为了包含模板使用的CSS样式,这里使用了bootstrap样式库。

编辑shop/product/list.html模板:

{% extends "shop/base.html" %}
{% load static %}
{% block title %}
 {% if category %}{{ category.name }}{% else %}Products{% endif %}
{% endblock %}
{% block content %}
    <div class="row">
        <div class="col-3" style="margin-top: 60px; padding: 10px;">
            <h3>Categories</h3>
            <div class="list-group">

                <a href="{% url 'shop:product_list' %}" {% if not category %} class="list-group-item list-group-item-action active"{%else%}
                class="list-group-item list-group-item-action"{% endif %}>All</a>

                {% for c in categories %}

                    <a href="{{ c.get_absolute_url }}" {% if category.slug == c.slug %}class="list-group-item list-group-item-action active"{%else%}
                    class="list-group-item list-group-item-action"
                    {% endif %}>{{ c.name }}</a>

                {% endfor %}
            </div>
        </div>
        <div class="col">
            <h1>{% if category %}{{ category.name }}{% else %}Products
            {% endif %}</h1>
            <div class="container">
                <div class="row">

                    {% for product in products %}
                    <div class="col text-center">
                        <a href="{{ product.get_absolute_url }}">
                        <img src="{% if product.image %}{{ product.image.url }}
                        {%else %}{% static 'shop/no_image.png' %}{% endif %}" style="width: 200px; height: 100px;">
                            </a>
                        <br>
                        <a href="{{ product.get_absolute_url }}" class="text-decoration-none">{{ product.name }}</a>
                        <br>
                        ${{ product.price }}
                    </div>
                    {% endfor %}

                </div>
            </div>

        </div>
    </div>
{% endblock %}
  • 这是产品列表模板。它扩展了shop/base.html模板,并使用categories上下文变量来显示侧边栏中的所有类别,使用products来显示当前页面的产品。两者都使用相同的模板:列出所有可用产品和列出按类别过滤的产品。
  • 当在模版中使用{{ product.get_absolute_url  }} 会使用product实例id和slug自动填充URL中的参数。
  • 由于产品图像字段可以为空白,需要为没有图像的产品提供默认图像。该图像位于静态文件目录中,相对路径为shop/static/shop/no_image.png。

编辑产品详细信息模板。
编辑shop/product/detail.html模板,并添加以下代码:

{% extends "shop/base.html" %}
{% load static %}
{% block title %}
{{ product.name }}
{% endblock %}
{% block content %}
    <div class="product-detail">
        <img src="{% if product.image %}{{ product.image.url }}{% else %}
        {% static 'img/no_image.png' %}{% endif %}">
        <h1>{{ product.name }}</h1>
        <h2><a href="{{ product.category.get_absolute_url }}">
            {{ product.category }}</a></h2>
        <p class="price">${{ product.price }}</p>
        {{ product.description|linebreaks }}
    </div>
{% endblock %}

列表页面预览

详情页面预览

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1395509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(9)-Fiddler如何设置捕获Https会话

1.简介 由于近几年来各大网站越来越注重安全性都改成了https协议&#xff0c;不像前十几年前直接是http协议直接裸奔在互联网。还有的小伙伴或者童鞋们按照上一篇宏哥的配置都配置好了&#xff0c;想大展身手抓一下百度的包&#xff0c;结果一试傻眼了&#xff0c;竟然毛都没有…

MyBatisX 基本使用

MyBatisX 插件&#xff0c;自动根据数据库生成 domain 实体对象、mapper、mapper.xml、service、serviceImpl。 MyBatisX 的使用&#xff1a; MyBatis-Plus依赖&#xff1a; <!--mybatisPlus--><dependency><groupId>com.baomidou</groupId><arti…

C/C++ BM6判断链表中是否有环

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 解决方案二2.1 思路阐述2.2 源码 总结 前言 做了一堆单链表单指针的题目&#xff0c;这次是个双指针题&#xff0c;这里双指针的作用非常明显。 题目 判断给定的链表中是否有环。如果有环则返回true&#xff0c;否则返回fal…

汇编和c++初学,c++字符串加整型,导致的字符串偏移

从汇编角度分析"helloworld"1 “helloworld”1对应 mov dword ptr [a],1 mov eax,dword ptr [a] add eax,offset string "helloworld" (03CCCBCh)eax地址偏移加了1&#xff0c; lea ecx,[test]最终取的内存偏移地址&#xf…

windows安装mysql5.7

看了如何学习mysql后&#xff0c;就开始本地安装mysql&#xff0c;开始学习了。 1.官网下载 官网地址&#xff1a; https://dev.mysql.com/downloads/mysql/ 选择5.7版本 点击 “No thanks, just start my download”开始下载 下载64位的压缩包版 解压下载好的.zip文件&#xf…

数学领域的经典教材有哪些

有本书叫做《自然哲学的数学原理》&#xff0c;是牛顿写的&#xff0c;读完之后你就会感叹牛顿的厉害之处! 原文完整版PDF&#xff1a;https://pan.quark.cn/s/a817a228b7bf 那玩意真的是人写出来的么… 现代教材把牛顿力学简化成三定律&#xff0c;当然觉得很简单。只有读了原…

流程效率分析方案

流程效率分析 流程效率分析方案概述功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个注脚注释也是必不可…

LaWGPT安装和使用教程的复现版本【细节满满】

文章目录 前言一、下载和部署1.1 下载1.2 环境安装1.3 模型推理 总结 前言 LaWGPT 是一系列基于中文法律知识的开源大语言模型。该系列模型在通用中文基座模型&#xff08;如 Chinese-LLaMA、ChatGLM等&#xff09;的基础上扩充法律领域专有词表、大规模中文法律语料预训练&am…

C语言总结十三:程序环境和预处理详细总结

了解程序的运行环境可以让我们更加清楚的程序的底层运行的每一个步骤和过程&#xff0c;做到心中有数&#xff0c;预处理阶段是在预编译阶段完成&#xff0c;掌握常用的预处理命令语法&#xff0c;可以让我们正确的使用预处理命令&#xff0c;从而提高代码的开发能力和阅读别人…

Unity Mirror VR联机开发 实战篇(二)

一、迁移示例中的联机物体 1、将MirrorExamplesVR工程中的部分文件夹复制到自己的工程中。 1、打开MirrorExamplesVR中的 SceneVR-Common场景。 2、将场景中没用的东西都删掉&#xff0c;只留下面这些&#xff0c;新建一个空物体XR Mirror&#xff0c;将所有剩下的物体拖成XR …

酷开科技将AR技术多方应用 打造全能酷开系统

酷开系统AR技术的核心是通过计算机视觉、图形渲染和深度感知等技术&#xff0c;将虚拟物体或信息精确地叠加到现实世界的场景中。通过智能摄像头捕捉真实环境的图像和视频&#xff0c;结合3D渲染技术&#xff0c;生成与现实场景相融合的虚拟图像&#xff0c;实现虚实结合的视觉…

【目标检测】YOLOv7算法实现(二):正样本匹配(SimOTA)与损失计算

本系列文章记录本人硕士阶段YOLO系列目标检测算法自学及其代码实现的过程。其中算法具体实现借鉴于ultralytics YOLO源码Github&#xff0c;删减了源码中部分内容&#xff0c;满足个人科研需求。   本篇文章在YOLOv5算法实现的基础上&#xff0c;进一步完成YOLOv7算法的实现。…

启扬方案:新能源电站功率预测系统数据采集设备解决方案

根据国家能源局发布数据显示&#xff0c;截至8月底&#xff0c;全国发电装机容量约24.7亿千瓦&#xff0c;同比增长8.0%。其中风电装机容量约3.4亿千瓦&#xff0c;同比增长16.6%&#xff1b;太阳能发电装机容量约3.5亿千瓦&#xff0c;同比增长27.2%。随着以风力发电、光伏发电…

基于高斯过程的贝叶斯优化

基于Bayes_opt实现GP优化 bayes-optimization是最早开源的贝叶斯优化库之一&#xff0c;也是为数不多至今依然保留着高斯过程优化的优化库。由于开源较早、代码简单&#xff0c;bayes-opt常常出现在论文、竞赛kernels或网络学习材料当中&#xff0c;因此理解Bayes_opt的代码是…

2024 前端高频面试题之 HTML/CSS 篇

【前言】随着市场的逐渐恶劣&#xff0c;通过总结面试题的方式来帮助更多的coder&#xff0c;也是记录自己的学习过程&#xff0c;温故而知新。欢迎各位同胞大大点评补充~ 前端面试题之 HTML/CSS 篇 1、HTML 语义化&#xff1f;2、块级元素&内联样式3、盒子模型的理解&…

重磅发布!基于百度飞桨的《人工智能基础及应用》书籍正式上线

科技日新月异的今天&#xff0c;人工智能已经成为引领未来的核心驱动力。为了帮助大家更好地深入理解人工智能的理论和技术&#xff0c;为未来发展做好准备&#xff0c;百度飞桨教材编写组联合北京交通大学王方石教授、北京邮电大学杨煜清特聘副研究员共同撰写推出了《人工智能…

大语言模型漏洞缓解指南

虽然大语言模型(LLM)应用正在全球快速普及&#xff0c;但企业对大语言模型的威胁态势仍然缺乏全面了解。面对大语言模型风险的不确定性&#xff0c;企业希望在保障其安全性的基础上加快应用脚步&#xff0c;用人工智能提升企业核心竞争力&#xff0c;这意味着企业的CISO面临着理…

用 Python 制作可视化 GUI 界面,一键实现证件照背景颜色的替换

今天&#xff0c;我们来分享一下如何通过Python的十来行代码来替换证件照的背景颜色&#xff0c;那么在最后&#xff0c;小编也会将上述的流程制作成一个GUI界面来方便大家使用。关于界面的大致模样其实和先前的相差不大&#xff0c;大家应该都看过上一篇的内容 界面大体的样子…

C#MQTT编程08--MQTT服务器和客户端(cmd版)

1、前言 前面完成了winform版&#xff0c;wpf版&#xff0c;为什么要搞个cmd版&#xff0c;因为前面介绍了mqtt的报文结构&#xff0c;重点分析了【连接报文】&#xff0c;【订阅报文】&#xff0c;【发布报文】&#xff0c;这节就要就看看实际报文是怎么组装的&#xff0c;这…

问题解决:No module named ‘apex‘,apex安装

最近Git了一个别人的程序&#xff0c;跑的过程中遇到了报错&#xff1a; No module named apex 关于Apex&#xff0c;官方介绍是&#xff1a;该资源库包含英伟达维护的实用程序&#xff0c;用于简化 Pytorch 中的混合精度和分布式训练。这里的部分代码最终将被纳入 Pytorch …