用 Django 5 快速生成一个简单 进销存 系统 添加 个打印 按钮

news2024/11/20 4:44:20

一、前置条件:

1.安装好python 【关联网址】

2. 安装好vscode 【关联网址】 

插件

3. 登陆海螺AI【关联网址】

4. 安装好 pip install django 【关联网址】 

pip install django -i https://mirrors.aliyun.com/pypi/simple/

二、开始生成

1. 打开vscode 打开终端输入以下命令

django-admin startproject myapp

cd myapp

py manage.py startapp app

# 下面生成 目录 用于修改后台,二次开发用
md templates/admin

2、数据库 对海螺AI  问 : 设计一个进销存数据库

设计一个进销存(Inventory Management System)数据库需要考虑几个关键实体和它们之间的关系。以下是一个基本的进销存数据库设计示例,包括了一些核心表和它们的字段。

### 核心实体和字段

#### 1. 商品(Products)
- 商品ID(ProductID): 主键,唯一标识每个商品。
- 商品名称(ProductName): 商品的名称。
- 商品描述(Description): 商品的详细描述。
- 单位成本(CostPrice): 商品的采购成本。
- 销售价格(SellingPrice): 商品的销售价格。
- 库存数量(StockQuantity): 当前库存中的商品数量。
- 分类ID(CategoryID): 外键,关联到商品分类表。

#### 2. 商品分类(Categories)
- 分类ID(CategoryID): 主键,唯一标识每个分类。
- 分类名称(CategoryName): 分类的名称。

#### 3. 供应商(Suppliers)
- 供应商ID(SupplierID): 主键,唯一标识每个供应商。
- 供应商名称(SupplierName): 供应商的名称。
- 联系信息(ContactInfo): 供应商的联系信息。

#### 4. 客户(Customers)
- 客户ID(CustomerID): 主键,唯一标识每个客户。
- 客户名称(CustomerName): 客户的名称。
- 联系信息(ContactInfo): 客户的联系信息。

#### 5. 订单(Orders)
- 订单ID(OrderID): 主键,唯一标识每个订单。
- 客户ID(CustomerID): 外键,关联到客户表。
- 订单日期(OrderDate): 订单的日期。
- 总金额(TotalAmount): 订单的总金额。

#### 6. 订单详情(OrderDetails)
- 订单详情ID(OrderDetailID): 主键,唯一标识订单详情。
- 订单ID(OrderID): 外键,关联到订单表。
- 商品ID(ProductID): 外键,关联到商品表。
- 购买数量(QuantityPurchased): 购买的商品数量。
- 单价(UnitPrice): 购买时的商品单价。

#### 7. 采购记录(Purchases)
- 采购记录ID(PurchaseID): 主键,唯一标识每次采购。
- 供应商ID(SupplierID): 外键,关联到供应商表。
- 采购日期(PurchaseDate): 采购的日期。
- 总金额(TotalCost): 采购的总金额。

#### 8. 采购详情(PurchaseDetails)
- 采购详情ID(PurchaseDetailID): 主键,唯一标识采购详情。
- 采购记录ID(PurchaseID): 外键,关联到采购记录表。
- 商品ID(ProductID): 外键,关联到商品表。
- 购入数量(QuantityReceived): 购入的商品数量。
- 单价(UnitPrice): 购入时的商品单价。

### 关系
- 商品与分类是多对一的关系,即一个商品属于一个分类,一个分类可以包含多个商品。
- 订单与客户是多对一的关系,即一个客户可以有多个订单,但每个订单只属于一个客户。
- 订单详情与订单是多对一的关系,即一个订单可以包含多个商品,但每个订单详情只属于一个订单。
- 订单详情与商品是多对一的关系,即一个商品可以在多个订单中出现,但每个订单详情只涉及一个商品。
- 采购记录与供应商是多对一的关系,即一个供应商可以有多次采购记录,但每次采购记录只对应一个供应商。
- 采购详情与采购记录是多对一的关系,即一次采购记录可以包含多个商品,但每个采购详情只属于一次采购记录。
- 采购详情与商品是多对一的关系,即一个商品可以被多次采购,但每个采购详情只涉及一个商品。

### 数据库设计注意事项
- 确保主键的唯一性。
- 使用外键来维护表之间的关系。
- 考虑索引的使用,以提高查询效率。
- 根据实际业务需求,可能还需要添加额外的字段或表,例如员工信息、库存变动记录等。

这个设计是一个基础版本,实际应用中可能需要根据具体业务需求进行调整和扩展。

第二问:根据上面的数据库生成django 5 的models

第三问:舔加中文标识

第四问:生成admin.py

三、 再改生成app/models.py

from django.db import models

# 商品分类模型
class Category(models.Model):
    category_name = models.CharField("分类名称", max_length=100, unique=True)
    # 其他字段...
    class Meta:
        verbose_name = "分类"
        verbose_name_plural = "分类"

    def __str__(self):
        return self.category_name

# 商品模型
class Product(models.Model):
    product_name = models.CharField("商品名称", max_length=255)
    description = models.TextField("商品描述")
    cost_price = models.DecimalField("成本价格", max_digits=10, decimal_places=2)
    selling_price = models.DecimalField("销售价格", max_digits=10, decimal_places=2)
    stock_quantity = models.IntegerField("库存数量")
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name="分类")

    class Meta:
        verbose_name = "商品"
        verbose_name_plural = "商品"
    def __str__(self):
        return self.product_name

# 供应商模型
class Supplier(models.Model):
    supplier_name = models.CharField("供应商名称", max_length=255)
    contact_info = models.TextField("联系信息")
    address = models.CharField("地址", max_length=255, blank=True, null=True)
    phone_number = models.CharField("电话号码", max_length=20, blank=True, null=True)

    class Meta:
        verbose_name = "供应商"
        verbose_name_plural = "供应商"

    def __str__(self):
        return self.supplier_name

# 客户模型
class Customer(models.Model):
    customer_name = models.CharField("客户名称", max_length=255)
    contact_info = models.TextField("联系信息")
    address = models.TextField("地址", blank=True, null=True)
    phone_number = models.CharField("电话号码", max_length=20, blank=True, null=True)

    class Meta:
        verbose_name = "客户"
        verbose_name_plural = "客户"

    def __str__(self):
        return self.customer_name

# 订单模型
class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, verbose_name="客户")
    order_date = models.DateTimeField("订单日期", auto_now_add=True)
    total_amount = models.DecimalField("总金额", max_digits=10, decimal_places=2)

    class Meta:
        verbose_name = "订单"
        verbose_name_plural = "订单"
    def __str__(self):
        return f"订单 {self.id} 由 {self.customer}"

# 订单详情模型
class OrderDetail(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name="订单")
    product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="商品")
    quantity_purchased = models.IntegerField("购买数量")
    unit_price = models.DecimalField("单价", max_digits=10, decimal_places=2)

    class Meta:
        verbose_name = "订单详情"
        verbose_name_plural = "订单详情"
    def __str__(self):
        return f"{self.quantity_purchased} 个 {self.product} 在订单 {self.order}"

# 采购记录模型
class Purchase(models.Model):
    supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, verbose_name="供应商")
    purchase_date = models.DateTimeField("采购日期", auto_now_add=True)
    total_cost = models.DecimalField("总成本", max_digits=10, decimal_places=2)

    class Meta:
        verbose_name = "采购记录"
        verbose_name_plural = "采购记录"
    def __str__(self):
        return f"采购 {self.id} 来自 {self.supplier}"

# 采购详情模型
class PurchaseDetail(models.Model):
    purchase = models.ForeignKey(Purchase, on_delete=models.CASCADE, verbose_name="采购")
    product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name="商品")
    quantity_received = models.IntegerField("接收数量")
    unit_price = models.DecimalField("单价", max_digits=10, decimal_places=2)

    class Meta:
        verbose_name = "采购详情"
        verbose_name_plural = "采购详情"
    def __str__(self):
        return f"{self.quantity_received} 个 {self.product} 在采购 {self.purchase}"

 app/admin.py

from django.contrib import admin
from .models import Category, Product, Supplier, Customer, Order, OrderDetail, Purchase, PurchaseDetail



# 定义一个内联类用于在订单详情中显示商品信息
class OrderDetailInline(admin.TabularInline):
    model = OrderDetail
    extra = 1  # 默认显示额外的1行

# 定义一个内联类用于在采购详情中显示商品信息
class PurchaseDetailInline(admin.TabularInline):
    model = PurchaseDetail
    extra = 1  # 默认显示额外的1行

# 定义Category模型的管理类
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('category_name',)  # 在列表页显示的字段

# 定义Product模型的管理类
class ProductAdmin(admin.ModelAdmin):
    list_display = ('id','product_name','selling_price', 'category', 'stock_quantity')
    search_fields = ('product_name', 'id')

# 定义Supplier模型的管理类
class SupplierAdmin(admin.ModelAdmin):
    list_display = ('id','supplier_name', 'phone_number', 'address')
    search_fields = ('supplier_name', 'id')

# 定义Customer 客户模型的管理类
class CustomerAdmin(admin.ModelAdmin):
    list_display = ('customer_name', 'phone_number')
    search_fields = ('customer_name', 'id')

# 定义Order订单模型的管理类
class OrderAdmin(admin.ModelAdmin):
    list_display = ('id', 'customer', 'order_date', 'total_amount')
    inlines = [OrderDetailInline]  # 使用内联类显示订单详情
    search_fields = ('id', 'customer__customer_name')

# 定义Purchase模型的管理类
class PurchaseAdmin(admin.ModelAdmin):
    list_display = ('id', 'supplier', 'purchase_date', 'total_cost')
    inlines = [PurchaseDetailInline]  # 使用内联类显示采购详情
    search_fields = ('id', 'supplier__supplier_name')

# 注册模型到admin
admin.site.register(Category, CategoryAdmin)
admin.site.register(Product, ProductAdmin)
admin.site.register(Supplier, SupplierAdmin)
admin.site.register(Customer, CustomerAdmin)
admin.site.register(Order, OrderAdmin)
admin.site.register(Purchase, PurchaseAdmin)

主urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('', admin.site.urls),  # Django自带的管理界面URLs
]

 设置:settings.py

 四、输入命令 生成Django 数据库 db.sqlite3

# 生成模型转到数据库
python manage.py makemigrations
python manage.py migrate

# 创建管理员
python manage.py createsuperuser

# 可填写入:admin   email:admin@qq.com  密码:abc123456

 五、根目录 建 templates/admin

 根据 templates/admin 目录优先 打后台的网页拿过来改从而得到覆盖原先页面来改后台页面

C:\Program Files\Python312\Lib\site-packages\django\contrib\admin\templates\admin

复制到:templates/admin

\myapp\templates\admin\change_form.html

{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}

{% block extrahead %}{{ block.super }}
<script src="{% url 'admin:jsi18n' %}"></script>
<style>
  /* 对打印机进行样式设置 */
@media print {
    .no-print {
      display: none; /* 在打印时隐藏带有no-print类的元素 */
    }
    td,th, tr,table {
      border: none;
      /* padding: 15px; */
    }
    .submit-row {
      display: none;
    }
    body {
      margin: 0;
      padding: 0;
      border: none;
    }
    #site-name {
      display: none;
    }
    @page {
    margin-top: 0;
    margin-bottom: 0;
  }
  header, footer {
    display: none;
  }
  /* 或者 */
  header, footer {
    visibility: hidden;
    position: absolute;
    top: -10000px;
  }

  }
</style>
{{ media }}
{% endblock %}

{% block extrastyle %}{{ block.super }}<link rel="stylesheet" href="{% static "admin/css/forms.css" %}">{% endblock %}

{% block coltype %}colM{% endblock %}

{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}

{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
&rsaquo; <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
&rsaquo; {% if has_view_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
&rsaquo; {% if add %}{% blocktranslate with name=opts.verbose_name %}Add {{ name }}{% endblocktranslate %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% endif %}

{% block content %}<div id="content-main">
{% block object-tools %}
{% if change and not is_popup %}
  <ul class="object-tools">
    {% block object-tools-items %}
      {% change_form_object_tools %}
    {% endblock %}
  </ul>
{% endif %}
{% endblock %}
<form {% if has_file_field %}enctype="multipart/form-data" {% endif %}{% if form_url %}action="{{ form_url }}" {% endif %}method="post" id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
{% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
{% if errors %}
    <p class="errornote">
    {% blocktranslate count counter=errors|length %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktranslate %}
    </p>
    {{ adminform.form.non_field_errors }}
{% endif %}

{% block field_sets %}
{% for fieldset in adminform %}
  {% include "admin/includes/fieldset.html" with heading_level=2 prefix="fieldset" id_prefix=0 id_suffix=forloop.counter0 %}
{% endfor %}
{% endblock %}

{% block after_field_sets %}{% endblock %}

{% block inline_field_sets %}
{% for inline_admin_formset in inline_admin_formsets %}
    {% include inline_admin_formset.opts.template %}
{% endfor %}
{% endblock %}

{% block after_related_objects %}{% endblock %}

{% block submit_buttons_bottom %}{% submit_row %}{% endblock %}

<div class="submit-row">
  <button onclick="printDocument()" class="btn" style="background-color: rgb(22, 194, 247);height: 35px;width: 80px;border-radius: 5px;border: none;color: #fff;" >打印</button>
</div>

{% block admin_change_form_document_ready %}
    <script id="django-admin-form-add-constants"
            src="{% static 'admin/js/change_form.js' %}"
            {% if adminform and add %}
                data-model-name="{{ opts.model_name }}"
            {% endif %}
            async>
    </script>
{% endblock %}

{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}

</div>
</form></div>
<script>
  function printDocument() {
    window.print();
}
    </script>
</script>
{% endblock %}

用了CSS 隐藏的方法来和改变样式的 来做个用浏览器打印的方法

@media print {
    .no-print {
      display: none; /* 在打印时隐藏带有no-print类的元素 */
    }

@page {    ---------------去掉页眉 页脚
    margin-top: 0;
    margin-bottom: 0;
  }

调用浏览器来打印

<button οnclick="printDocument()"

window.print();

 

contine......更多的细节后面分解

运行起来

python manage.py runserver  

不想看到 下面的日志

就在settings.py 加入下面这个

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': 'general.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

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

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

相关文章

[数据库实验五] 审计及触发器

一、实验目的与要求&#xff1a; 1.了解MySQL审计功能及实现方式 2.掌握触发器的工作原理、定义及操作方法 二、实验内容&#xff1a; 注&#xff1a; 在同一个触发器内编写多行代码&#xff0c;需要用结构begin ……end 函数current_user()获得当前登录用户名 1.自动保存…

Linux 应用层自定义协议与序列化

文章目录 一、应用层1、协议2、序列化 && 反序列化3、通过Json库进行数据的序列化 && 反序列化Json::Value类Json::Reader类Json::Writer类 二、为什么read、write、recv、send和Tcp支持全双工&#xff1f;发数据的本质&#xff1a;tcp支持全双工通信的原因&am…

gitlab-runner集成CI/CD完整项目部署

目录 1.环境安装 2.gitlab代码仓库搭建 3.gitlab-runner-安装以及注册 4..gitlab-ci.yml脚本 5.脚本说明 6.build.sh 7.test.sh 8. deploy.sh 9.运行流水线 10.选择流水线分支 11.查看运行阶段 12.查看运行日志 13.查看服务器真实日志 1.环境安装 确保服务器的Java环…

Python_异常机制

软件程序在运行过程中&#xff0c;非常可能遇到刚刚提到的这些问题&#xff0c;我们称之为异常&#xff0c;英文是&#xff1a;Exception&#xff0c;意思是例外。遇到这些例外情况&#xff0c;或者叫异常&#xff0c;我们怎么让写的程序做出合理的处理&#xff0c;安全的退出&…

Footprint Growthly Quest 工具:赋能 Telegram 社区实现 Web3 飞速增长

作者&#xff1a;Stella L (stellafootprint.network) 在 Web3 的快节奏世界里&#xff0c;社区互动是关键。而众多 Web3 社区之所以能够蓬勃发展&#xff0c;很大程度上得益于 Telegram 平台。正因如此&#xff0c;Footprint Analytics 精心打造了 Growthly —— 一款专为 Tel…

Tkinter制作登录界面以及登陆后页面切换

Tkinter制作登录界面以及登陆后页面切换 前言序言1. 由来2. 思路3. 项目结构描述4. 项目实战1. 登录界面实现&#xff08;代码&#xff09;2. 首页界面实现&#xff08;代码&#xff09;3. 打包build.py&#xff08;与main.py同级目录&#xff09;4. 打包安装包 前言 本帖子&a…

【nrm】npm 注册表管理器

nrm是什么 nrm&#xff08;NPM Registry Manager&#xff09;是一个用于管理 Node.js 包管理器&#xff08;如 npm 和 Yarn&#xff09;的注册表工具。它可以帮助用户快速切换不同的 npm 源&#xff0c;以便于提高包安装的速度和效率&#xff0c;特别是在中国大陆地区&#xf…

Ubuntu23.10下处理libncurses5-dev包的安装问题

Ubuntu23.10下处理libncurses5-dev包的安装问题 导语环境准备问题和解决方案总结参考文献 导语 使用Ubuntu23.10的时候&#xff0c;遇到需要termios的场景&#xff0c;结果发现无论是codeblocks还是系统本身的gcc都无法找到term.h和curse.h&#xff0c;网上找了很多解决方案都…

了解云计算工作负载保护的重要性,确保数据和应用程序安全

云计算de小白 云计算技术的快速发展使数据和应用程序安全成为一种关键需求&#xff0c;而不仅仅是一种偏好。随着越来越多的客户公司将业务迁移到云端&#xff0c;保护他们的云工作负载&#xff08;指所有部署的应用程序和服务&#xff09;变得越来越重要。云工作负载保护&…

【stm32】TIM定时器输出比较-PWM驱动LED呼吸灯/舵机/直流电机

TIM定时器输出比较 一、输出比较简介1、OC&#xff08;Output Compare&#xff09;输出比较2、PWM简介3、输出比较通道(高级)4、输出比较通道(通用)5、输出比较模式6、PWM基本结构配置步骤&#xff1a;程序代码&#xff1a;PWM驱动LED呼吸灯 7、参数计算8、舵机简介程序代码&am…

nginx 安装(Centos)

nginx 安装-适用于 Centos 7.x [rootiZhp35weqb4z7gvuh357fbZ ~]# lsb_release -a LSB Version: :core-4.1-amd64:core-4.1-noarch Distributor ID: CentOS Description: CentOS Linux release 7.9.2009 (Core) Release: 7.9.2009 Codename: Core# 创建文件…

大模型训练:K8s 环境中数千节点存储最佳实践

今天这篇博客来自全栈工程师朱唯唯&#xff0c;她在前不久举办的 KubeCon 中国大会上进行了该主题分享。 Kubernetes 已经成为事实的应用编排标准&#xff0c;越来越多的应用在不断的向云原生靠拢。与此同时&#xff0c;人工智能技术的迅速发展&#xff0c;尤其是大型语言模型&…

智慧政务助力实现服务民生新突破

在数字化转型的浪潮中&#xff0c;中国移动紧密结合人工智能&#xff08;AI&#xff09;技术&#xff0c;推动政务服务的智能化升级。近日&#xff0c;中国移动正式发布政务大模型3.0版本&#xff0c;以科技创新提升政务效率&#xff0c;实现服务民生的新突破。 为什么…

【Android】页面启动耗时统计流程梳理

文章基于Android 11 写在前面&#xff1a; 最近的文章都会放流程图&#xff0c;时序图之类的图片&#xff0c;解释下为什么这么做&#xff1a; 图片的好处&#xff1a; 流程清晰&#xff0c;一目了然很多代码&#xff0c;如同老太太的裹脚布&#xff0c;又臭又长。影响理解&a…

Python的Pandas库学习指南

应用场景 Pandas库因其强大的数据处理和分析能力&#xff0c;在数据科学和数据分析领域有着广泛的应用。 1. 数据清洗 处理缺失数据&#xff1a;通过删除或填充缺失值来清洗数据。数据类型转换&#xff1a;将数据转换为合适的格式&#xff0c;例如将日期字符串转换为日期类型…

k8s_资源管理介绍

资源管理介绍 在k8s中&#xff0c;所有内容都抽象成资源&#xff0c;用户需要通过操作资源来管理k8s k8s本身就是一个集群系统&#xff0c;用户可以在集群中部署服务&#xff0c;在k8s集群中运行一个个的容器&#xff0c;将指定的程序部署到容器中 k8s最小的管理单元是pod&…

AI-Talk开发板之wifi scan

一、说明 AI-Talk开发板使用ESP32-C3扩展WIFI通信功能&#xff0c;与CSK6011A通过SPI接口通信。 与处理器的信号连接&#xff1a; ESP32-C3需要烧录hosted固件&#xff0c;参考&#xff1a;AI-Talk开发板更新ESP32固件_esp32 固件-CSDN博客 二、工程 1、创建项目 进入exampl…

本地编译安装|编译安装最新版postgis3.4.3版本指南

一、本地编译安装步骤介绍 本地编译&#xff0c;指的是在本地环境编译安装某个软件&#xff0c;例如&#xff0c;本文所述的最新版postgis3.4.3&#xff0c;本地是什么cpu架构&#xff0c;编译完成后&#xff0c;编译产出物就可以在其它的同cpu架构的服务器上直接适用了&#…

关于JAVA中Scanner和sout读取超时问题

1.Scanner与System.out为什么慢 Scanner读取速度慢的原因&#xff1a; 在ACM模式下&#xff0c;输入数据和输出数据时&#xff0c;他会将数据放在一个文件里面 在new上一个Scanner时&#xff0c;去调用一个next&#xff08;&#xff09;方法&#xff0c;他会去访问IO设备&…

【mac开发入坑指南】能让你的终端好用一万倍的神仙组合iTerm2 + oh-my-zsh

介绍 iTerm2 iTerm2是默认终端的替代品&#xff0c;也是目前Mac系统下最好用的终端工具&#xff0c;集颜值和效率于一身。 Oh-My-Zsh Oh My Zsh 是一款社区驱动的命令行工具&#xff0c;正如它的主页上说的&#xff0c;Oh My Zsh 是一种生活方式。 它基于Zsh 命令行&#xff0c…