Django 5 增删改查 小练习

1. 用命令创建目录和框架

django-admin startproject myapp

cd myapp

py manage.py startapp app

md templates

md static

md media

2. Ai 生成代码

一、app/models.py

python 复制代码
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=255, verbose_name="商品名称")
    description = models.TextField( verbose_name="商品描述")
    quantity = models.PositiveIntegerField( verbose_name="商品数量")
    price = models.DecimalField(max_digits=10, decimal_places=2 , verbose_name="商品价格")
    class Meta:
        verbose_name = "商品"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Sale(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE , verbose_name="商品")
    quantity_sold = models.PositiveIntegerField( verbose_name="销售数量")
    sale_date = models.DateTimeField(auto_now_add=True , verbose_name="销售日期")
    class Meta:
        verbose_name = "销售"
        verbose_name_plural = verbose_name

class Purchase(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE , verbose_name="商品")
    quantity_purchased = models.PositiveIntegerField( verbose_name="购买数量")
    purchase_date = models.DateTimeField(auto_now_add=True , verbose_name="购买日期")
    class Meta:
        verbose_name = "购买"
        verbose_name_plural = verbose_name

二、myapp/settings.py

python 复制代码
ALLOWED_HOSTS = ['*']

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app',
]


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [ BASE_DIR / 'templates'],
        'APP_DIRS': True,

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'


STATIC_URL = 'static/'
# STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

三、命令创建数据库

python manage.py makemigrations

python manage.py migrate

四、app/admin.py

python 复制代码
from django.contrib import admin
from.models import Product, Sale, Purchase

admin.site.register(Product)
admin.site.register(Sale)
admin.site.register(Purchase)

python manage.py createsuperuser # 创建后台用户 admin test@qq.com 123456 y

五、app/views.py

python 复制代码
from django.shortcuts import render, redirect
from.models import Product

def product_list(request):
    products = Product.objects.all()
    total_quantity = sum(product.quantity for product in products)
    total_price = sum(product.price * product.quantity for product in products)
    return render(request, 'product_list.html', {'products': products, 'total_quantity': total_quantity, 'total_price': total_price})

def add_product(request):
    if request.method == 'POST':
        name = request.POST['name']
        description = request.POST['description']
        quantity = int(request.POST['quantity'])
        price = float(request.POST['price'])
        product = Product(name=name, description=description, quantity=quantity, price=price)
        product.save()
        return redirect('product_list')
    return render(request, 'add_product.html')

def update_product(request, product_id):
    product = Product.objects.get(pk=product_id)
    if request.method == 'POST':
        product.name = request.POST['name']
        product.description = request.POST['description']
        product.quantity = int(request.POST['quantity'])
        product.price = float(request.POST['price'])
        product.save()
        return redirect('product_list')
    return render(request, 'update_product.html', {'product': product})

def delete_product(request, product_id):
    product = Product.objects.get(pk=product_id)
    if request.method == 'POST':
        product.delete()
        return redirect('product_list')
    return render(request, 'delete_product.html', {'product': product})

六、app/urls.py

python 复制代码
from django.urls import path
from.views import product_list, add_product, update_product, delete_product

urlpatterns = [
    path('products/', product_list, name='product_list'),
    path('products/add/', add_product, name='add_product'),
    path('products/update/<int:product_id>/', update_product, name='update_product'),
    path('products/delete/<int:product_id>/', delete_product, name='delete_product'),
]

七、myapp/urls.py

python 复制代码
from django.contrib import admin
from django.urls import include, path

from app.views import product_list # 导入的视图函数 

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', product_list, name='home'), # 将根路径映射到 product_list 视图函数
    path('app/', include('app.urls')), # 将 app 应用中的 URL 映射到 app.urls 模块
]

八、myapp/templates 和 myapp/static

在 static 目录下载 layui (Layui - 极简模块化前端 UI 组件库(官方文档)) 解压到目录

在 templates 创建 product_list.html、add_product.html、delete_product.html、update_product.html

product_list.html

html 复制代码
<!DOCTYPE html>
<html>
    {% load static %}
<head>
    <title>Product List</title>
    <link rel="stylesheet" type="text/css" href="{% static 'layui/css/layui.css' %}">
</head>

<body>
    <div class="layui-container">
    <h1>Product List 商品列表</h1>
    <table class="layui-table" lay-skin="line" lay-even>
        <thead>
            <tr>
                <th>Name商品名称</th>
                <th>Description 商品描述</th>
                <th>Quantity 数量</th>
                <th>Price 单价</th>
                <th>Actions </th>
            </tr>
        </thead>
        <tbody>
            {% for product in products %}
            <tr>
                <td>{{ product.name }}</td>
                <td>{{ product.description }}</td>
                <td>{{ product.quantity }}</td>
                <td>{{ product.price }}</td>
                <td>
                    <a href="{% url 'update_product' product.id %}" class="layui-btn layui-btn-sm layui-btn-normal">Update 修改</a>
                    <a href="{% url 'delete_product' product.id %}" class="layui-btn layui-btn-sm layui-btn-danger">Delete 删除</a>
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    
    <h2>Total Quantity 数量: {{ total_quantity }}</h2>
    <h2>Total Price 总价: {{ total_price }}</h2>
    
    <a href="{% url 'add_product' %}" class="layui-btn layui-btn-primary">Add Product 增加</a>
    </div>
</body>

</html>

add_product.html

html 复制代码
<!DOCTYPE html>
<html>
{% load static %}
<head>
    <title>Add Product</title>
    <link rel="stylesheet" type="text/css" href="{% static 'layui/css/layui.css' %}">
</head>

<body>
    <div class="layui-container">
    <h1>Add Product</h1>
    <form method="post">
        {% csrf_token %}
        <label for="name">Name:</label>
        <input type="text" id="name" name="name" required class="layui-input"><br>
        <label for="description">Description:</label>
        <textarea id="description" name="description" class="layui-textarea"></textarea><br>
        <label for="quantity">Quantity:</label>
        <input type="number" id="quantity" name="quantity" required class="layui-input"><br>
        <label for="price">Price:</label>
        <input type="number" step="0.01" id="price" name="price" required class="layui-input"><br>
        <input type="submit" value="Add Product" class="layui-btn">
    </form>
</div>
</body>

</html>

delete_product.html

html 复制代码
<!DOCTYPE html>
<html>
    {% load static %}
<head>
    <title>Delete Product</title>
    <link rel="stylesheet" type="text/css" href="{% static 'layui/css/layui.css' %}">
</head>

<body>
    <div class="layui-container">
    <h1>Confirm Deletion </h1>
    <p>Are you sure you want to delete 是否要删除 "{{ product.name }}"?</p>
    <form method="post" class="layui-form" >
        {% csrf_token %}
        <input type="submit" value="Yes, Delete 删除" class="layui-btn layui-btn-danger">
        <a href="{% url 'product_list' %}" class="layui-btn layui-btn-primary">Cancel 取消</a>
    </form>
</div>
</body>

</html>

update_product.html

html 复制代码
<!DOCTYPE html>
<html>
    {% load static %}
<head>
    <title>Update Product</title>
    <link rel="stylesheet" type="text/css" href="{% static 'layui/css/layui.css' %}">
</head>

<body>
    <div class="layui-container">
    <h1>Update Product</h1>
    <form method="post">
        {% csrf_token %}
        <label for="name">Name:</label>
        <input type="text" id="name" name="name" value="{{ product.name }}" required class="layui-input"><br>
        <label for="description">Description:</label>
        <textarea id="description" name="description" class="layui-textarea" required>{{ product.description }}</textarea><br>
        <label for="quantity">Quantity:</label>
        <input type="number" id="quantity" name="quantity" value="{{ product.quantity }}" required class="layui-input"><br>
        <label for="price">Price:</label>
        <input type="number" step="0.01" id="price" name="price" value="{{ product.price }}" required class="layui-input"><br>
        <input type="submit" value="Update Product" class="layui-btn">
    </form>
    </div>
</body>

</html>

八、 运行

python manage.py runserver

3. 用TKinter 查看数据表 与出数据

pip install openpyxl

pip install reportlab

myapp/viewSQL.py

python 复制代码
import sqlite3
import tkinter as tk
from tkinter import ttk
import openpyxl
from tkinter import messagebox
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
import os

def get_table_names():
    conn = sqlite3.connect('db.sqlite3')
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
    table_names = [row[0] for row in cursor.fetchall()]
    conn.close()
    return table_names

def fetch_data(table_name):
    conn = sqlite3.connect('db.sqlite3')
    cursor = conn.cursor()
    cursor.execute(f'SELECT * FROM {table_name}')
    data = cursor.fetchall()
    conn.close()
    return data

def display_table_names():
    names = get_table_names()
    for item in tree.get_children():
        tree.delete(item)
    for name in names:
        tree.insert('', 'end', values=(name,))

def display_data_for_selected_table(event):
    selected_item = tree.focus()
    if selected_item:
        table_name = tree.item(selected_item)['values'][0]
        data = fetch_data(table_name)
        for item in data_tree.get_children():
            data_tree.delete(item)
        for row in data:
            data_tree.insert('', 'end', values=row)

def export_to_excel():
    selected_item = tree.focus()
    if selected_item:
        table_name = tree.item(selected_item)['values'][0]
        data = fetch_data(table_name)
        wb = openpyxl.Workbook()
        ws = wb.active
        ws.append([f'Column {i + 1}' for i in range(len(data[0]))])
        for row in data:
            ws.append(row)
        filename = f'{table_name}.xlsx'
        wb.save(filename)
        messagebox.showinfo("Export Success", f"Data exported to {filename}")

def print_to_pdf():
    selected_item = tree.focus()
    if selected_item:
        table_name = tree.item(selected_item)['values'][0]
        data = fetch_data(table_name)
        pdf_filename = f'{table_name}_pdf_export.pdf'
        c = canvas.Canvas(pdf_filename, pagesize=letter)
        y = 750
        c.setFont("Helvetica", 12)
        c.drawString(50, y, f"Table Name: {table_name}")
        y -= 20
        for row in data:
            row_str = ", ".join(str(item) for item in row)
            c.drawString(50, y, row_str)
            y -= 15
        c.save()
        messagebox.showinfo("PDF Export Success", f"Data printed to {pdf_filename}")

def print_to_markdown():
    selected_item = tree.focus()
    if selected_item:
        table_name = tree.item(selected_item)['values'][0]
        data = fetch_data(table_name)
        markdown_filename = f'{table_name}_markdown_export.md'
        with open(markdown_filename, 'w') as f:
            f.write(f'# {table_name}\n')
            for row in data:
                row_str = " | ".join(str(item) for item in row)
                f.write(f'| {row_str} |\n')
        messagebox.showinfo("Markdown Export Success", f"Data printed to {markdown_filename}")

root = tk.Tk()
root.title("SQLite3 Table Viewer and Exporter 查看器与导出器")

# Treeview for table names
tree = ttk.Treeview(root, columns=("Table Name",), show="headings")
tree.heading("Table Name", text="Table Name")
tree.column("Table Name", width=400)
tree.pack(padx=10, pady=10)

# Treeview for table data
data_tree = ttk.Treeview(root, columns=("column1", "column2", "column3", "column4", "column5", "..."), show="headings")
for col in ("column1", "column2", "column3", "column4", "column5", "..."):
    data_tree.heading(col, text=col)
    data_tree.column(col, width=100)
data_tree.pack(padx=10, pady=10)

button_fetch = tk.Button(root, text="Fetch Table Names 查看表名", command=display_table_names)
button_fetch.pack(pady=10)

export_button = tk.Button(root, text="Export to Excel 导出为Excel", command=export_to_excel)
export_button.pack(pady=10)

print_pdf_button = tk.Button(root, text="Print to PDF 打印为PDF", command=print_to_pdf)
print_pdf_button.pack(pady=10)

print_markdown_button = tk.Button(root, text="Print to Markdown 打印为Markdown", command=print_to_markdown)
print_markdown_button.pack(pady=10)

tree.bind("<Double-1>", display_data_for_selected_table)

root.mainloop()

4. 一键生成 代码

/app.py

python 复制代码
import subprocess
import os

def replace_content_in_file(file_path, keyword, new_content):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            lines = file.readlines()
        with open(file_path, 'w', encoding='utf-8') as file:
            for line in lines:
                if keyword in line:
                    line = line.replace(keyword, new_content)
                file.write(line)
        print(f"成功在文件中找到'{keyword}'并进行了替换。")
    except FileNotFoundError:
        print(f"文件 {file_path} 不存在。")
 
# 使用示例
# file_path = 'myapp/settings.py'
# keyword = 'ALLOWED_HOSTS = []'
# new_content = "ALLOWED_HOSTS = ['*']"
# replace_content_in_file(file_path, keyword, new_content)

def add_content_after_keyword(file_path, keyword, new_content):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            lines = file.readlines()
        with open(file_path, 'w', encoding='utf-8') as file:
            for line in lines:
                if keyword in line:
                    line = line.rstrip() + new_content + '\n'
                file.write(line)
        print(f"成功在文件中找到'{keyword}'并添加了内容。")
    except FileNotFoundError:
        print(f"文件 {file_path} 不存在。")
 
# 使用示例
# file_path = 'myapp/settings.py'
# keyword = "'django.contrib.staticfiles',"
# new_content = "\n\t'app',"



 
def create_django_project_and_app(project_name, app_name):
    try:
        # 创建 Django 项目
        subprocess.run(["django-admin", "startproject", project_name], check=True)
 
        # 切换到项目目录
        os.chdir(project_name)
 
        # 创建应用
        subprocess.run(["python", "manage.py", "startapp", app_name], check=True)
        # 创建templates目录
        os.makedirs('templates', exist_ok=True)
        # 创建 static 目录
        os.makedirs('static', exist_ok=True)
        # 创建media目录
        os.makedirs('media', exist_ok=True)

        file_path = project_name +'/settings.py'
        keyword = "'django.contrib.staticfiles',"
        new_content = "\n\t"+"'"+app_name+"'"+","
        add_content_after_keyword(file_path, keyword, new_content)

        file_path = project_name +'/settings.py'
        keyword = 'ALLOWED_HOSTS = []'
        new_content = "ALLOWED_HOSTS = ['*']"
        replace_content_in_file(file_path, keyword, new_content)

        file_path = project_name +'/settings.py'
        keyword = "'DIRS': [],"
        new_content = "'DIRS': [ BASE_DIR / 'templates'],"
        replace_content_in_file(file_path, keyword, new_content)

        file_path = project_name +'/settings.py'
        keyword = "LANGUAGE_CODE = 'en-us'"
        new_content = "LANGUAGE_CODE = 'zh-hans'"
        replace_content_in_file(file_path, keyword, new_content)

        file_path = project_name +'/settings.py'
        keyword = "TIME_ZONE = 'UTC'"
        new_content = "TIME_ZONE = 'Asia/Shanghai'"
        replace_content_in_file(file_path, keyword, new_content)

        file_path = project_name +'/settings.py'
        keyword = "from pathlib import Path"
        new_content = "from pathlib import Path\nimport os"
        replace_content_in_file(file_path, keyword, new_content)

        file_path = project_name +'/settings.py'
        keyword = "STATIC_URL = 'static/'"
        new_content = "STATIC_URL = 'static/'\nSTATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]\nMEDIA_URL = '/media/'\nMEDIA_ROOT = os.path.join(BASE_DIR, 'media')"
        replace_content_in_file(file_path, keyword, new_content)


        # 执行 makemigrations 命令
        subprocess.run(["python", "manage.py", "makemigrations"], check=True)

        # 执行 migrate 命令
        subprocess.run(["python", "manage.py", "migrate"], check=True)

        # 创建超级用户
        os.system("python manage.py createsuperuser")

        # 运行开发服务器
        subprocess.run(["python", "manage.py", "runserver"], check=True)
 
        print(f"成功创建 Django 项目:{project_name},并创建应用:{app_name}")
    except subprocess.CalledProcessError as e:
        print(f"创建过程中出现错误:{e}")
 
# 使用示例
# project_name = "myapp"
# app_name = "app"
project_name = input("请输入 Django 项目名称:")
app_name = input("请输入应用名称:")
create_django_project_and_app(project_name, app_name)
 
 
 


 
相关推荐
算法小白(真小白)1 小时前
低代码软件搭建自学第二天——构建拖拽功能
python·低代码·pyqt
唐小旭1 小时前
服务器建立-错误:pyenv环境建立后python版本不对
运维·服务器·python
007php0071 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
Chinese Red Guest2 小时前
python
开发语言·python·pygame
骑个小蜗牛2 小时前
Python 标准库:string——字符串操作
python
黄公子学安全4 小时前
Java的基础概念(一)
java·开发语言·python
程序员一诺5 小时前
【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】
后端·python
小木_.5 小时前
【Python 图片下载器】一款专门为爬虫制作的图片下载器,多线程下载,速度快,支持续传/图片缩放/图片压缩/图片转换
爬虫·python·学习·分享·批量下载·图片下载器
isSamle6 小时前
使用Vue+Django开发的旅游路书应用
前端·vue.js·django