Django 手鲁一个商品展示系统

发布时间 2023-08-30 22:36:32作者: 九尾cat

Django 手鲁一个商品展示系统

此商品展示系统包括一个Product模型,用于存储商品的名称、描述、价格和创建日期。有两个视图函数,一个用于显示所有商品的列表,另一个用于显示单个商品的详细信息。对应的URL模式定义在urls.py中。模板文件包括一个基本模板(base.html),以及两个特定于视图函数的模板(product_list.html和product_detail.html)。

要添加商品信息,可以在Django的后台管理界面中添加或修改Product模型实例。要展示商品信息,可以访问product_list视图函数对应的URL,即http://yourdomain.com/products/,这将会展示所有商品的列表。要查看单个商品的详细信息,可以点击商品名称或者访问 ,http://vourdomain.com/products/1/这样的URL,其中1是商品的ID号.  

1、 创建Django项目和应用

django-admin startproject goods_service
cd goods_service
python manage.py startapp goods

2、配置应用

  1. 在goods_service/settings.py文件的INSTALLED_APPS列表中添加myapp应用:
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'goods',
]

 

3 商品模型配置 models.py

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

 

4 视图配置views.py

### ### goods_service/goods/views.py
from django.shortcuts import render
from .models import Product

def product_list(request):
    products = Product.objects.all()
    return render(request, 'product_list.html', {'products': products})

def product_detail(request, pk):
    product = Product.objects.get(pk=pk)
    return render(request, 'product_detail.html', {'product': product})

5 路由配置urls.py

 

### ### goods_service/goods_service/urls.py
from django.contrib import admin
from django.urls import path
from goods.views import product_list, product_detail

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', product_list, name='product_list'),
    path('<int:pk>/', product_detail, name='product_detail'),
]

6 模版文件

product_list.html 模版优化

添加了一些CSS样式来定义.product-card类,使每个商品以卡片矩阵方式展示。我们还在每个商品卡片中添加了一个<img>标签来展示商品图片,并使用{{ product.photo.urll }}来获取商品图片的URL。

body选择器中添加了background-color属性来定义整个页面的背景颜色。你可以根据需要修改颜色值,选择一个柔和的背景颜色。同时,我们也在.product-card类中添加了background-color属性,用于定义商品卡片的背景颜色。

请注意,颜色值可以使用十六进制、RGB、RGBA等格式来表

 

<!DOCTYPE html>
<html>
<head>
  <title>My Goods</title>
  <style>
    body {
      background-color: #E1F5FE; /* 柔和的背景颜色 */
    }
    .product-card {
      display: inline-block;
      width: 300px;
      margin: 10px;
      padding: 10px;
      border: 1px solid #ccc;
      border-radius: 5px;
      text-align: left;
      background-color:  #DCEDC8; /* 商品卡片的背景颜色 */
    }

    .product-card img {
      width: 200px;
      height: 200px;
      object-fit: cover;
      margin-bottom: 10px;
    }
  </style>
</head>
<body>
  <nav>
    <ul>
      <li><a href="{% url 'product_list' %}">返回商品列表</a></li>
    </ul>
  </nav>
  <h1>商品信息:</h1>
  <div class="product-grid">
    {% for product in products %}
      <div class="product-card">
        <!-- <img src="{{ product.image.url }}" alt="{{ product.name }}"> -->
        <img src="{{ product.photo.url }}" alt="{{ product.name }}">
        <h3>商品名称: {{ product.name }}</h3>
        <h4>商品价格: {{ product.price }}</h4>
        <h4>商品创建时间: {{ product.created_at }}</h4>
        <p>商品描述: {{ product.description }}</p>
        <a href="{% url 'product_detail' product.pk %}">View Details</a>
      </div>
    {% endfor %}
  </div>
</body>
</html>

product_detail.html优化

 

<!DOCTYPE html>
<html>
<head>
  <title>My Goods</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      margin: 0;
      padding: 0;
      background: linear-gradient(to bottom, #f9d5e5, #ffe6e6);
    }
    header {
        background-color: #D3D3D3;
        color:  #000;
        padding: 10px;
        font-size: 36px;
        letter-spacing: 6px; /* 设置字间距为6像素 */
        line-height: 20px;
        text-align: center;
    }
    header img {
        float: left; /* 图标左浮动 */
        margin-right: 20px; /* 图标与标题间距 */
        height: 50px; /* 图标高度 */
    }
    nav {
      background-color: #333;
      color: #fff;
      display: flex;
      justify-content: flex-end;
      padding: 10px;
    }
    nav ul {
      list-style: none;
      margin: 0;
      padding: 0;
    }
    nav li {
      display: inline-block;
      margin-right: 20px;
    }
    nav a {
      color: #fff;
      text-decoration: none;
    }
    .container {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
      background-color: rgba(255, 255, 255, 0.8);
      border-radius: 10px;
      box-shadow: 0px 0px 10px rgba(0, 0, 0, 2);
      text-align: center;
    }
    .product-info {
      display: grid;
      grid-template-columns: 1fr;
      grid-gap: 10px;
      text-align: left;
      border: 2px solid #ccc;
      padding: 10px;
      border-radius: 5px;
    }
    .image-container {
      grid-row: 1 / span 2;
      grid-column: 1;
    }
    h3, h4, p {
      margin: 0;
    }
    img {
      max-width: 100%;
    }
    .btn {
      position: fixed;
      left: 20px;
      bottom: 20px;
      padding: 10px 20px;
      background-color: #ccc;
      border: none;
      border-radius: 5px;
      color: #fff;
    }
  </style>
</head>
<body>
  <header>
      <a href="/products/">
        <img src="/product_photos/wr.png" alt="logo">
      </a>
      <h2>商品详情</h2>
  </header>
  <div class="container">
    <h1>{{ product.name }}</h1>
    <div class="product-info">
      <div class="image-container">
        <img src="{{ product.photo.url }}" alt="{{ product.name }}">
      </div>
      <div class="text-container">
        <h3>商品名称: {{ product.name }}</h3>
        <h4>商品价格: {{ product.price }}</h4>
        <h4>商品创建时间: {{ product.created_at }}</h4>
        <p>商品描述: {{ product.description }}</p>
      </div>
    </div>
  </div>
  <a href="{% url 'product_list' %}" class="btn">
    <button>返回商品列表首页</button>
  </a>
</body>
</html>

product_form.html 

 

<!DOCTYPE html>
<html>
<head>
  <title>My Goods</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      background: linear-gradient(to bottom, #f9d5e5, #ffe6e6);
      margin: 0;
      padding: 0;
    }
    header {
        background-color: #D3D3D3;
        color:  #000;
        padding: 10px;
        font-size: 36px;
        letter-spacing: 6px; /* 设置字间距为6像素 */
        line-height: 20px;
        text-align: center;
    }
    header img {
        float: left; /* 图标左浮动 */
        margin-right: 20px; /* 图标与标题间距 */
        height: 50px; /* 图标高度 */
    }
    nav ul {
      list-style: none;
      margin: 0;
      padding: 0;
      background: #f2f2f2;
    }

    nav li {
      display: inline-block;
      margin-right: 10px;
    }

    nav a {
      display: block;
      padding: 10px;
      text-decoration: none;
      color: #333;
    }

    h1 {
      text-align: center;
      margin-top: 20px;
    }

    form {
      max-width: 400px;
      margin: 0 auto;
      padding: 20px;
      background: #fff;
      border-radius: 5px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    }

    label {
      display: block;
      margin-bottom: 10px;
    }

    input,
    textarea {
      width: 100%;
      padding: 10px;
      border: 1px solid #ccc;
      border-radius: 3px;
      box-sizing: border-box;
    }

    button {
      display: block;
      width: 100%;
      padding: 10px;
      margin-top: 10px;
      background: #4CAF50;
      color: #fff;
      border: none;
      border-radius: 3px;
      cursor: pointer;
    }

    button:hover {
      background: #45a049;
    }
    .btn {
      position: fixed;
      left: 20px;
      bottom: 20px;
      padding: 10px 20px;
      background-color: #ccc;
      border: none;
      border-radius: 5px;
      color: #fff;
    }
  </style>
</head>
<body>
  <header>
    <a href="/products/">
      <img src="/product_photos/wr.png" alt="logo">
    </a>
    <h2>新增商品信息</h2>
  </header>

  {% block content %}
    <h1>Add New Product</h1>
    <form method="POST" enctype="multipart/form-data">
      {% csrf_token %}
      <div>
        <label for="name">Name:</label>
        <input type="text" name="name" id="name">
      </div>
      <div>
        <label for="description">Description:</label>
        <textarea name="description" id="description"></textarea>
      </div>
      <div>
        <label for="price">Price:</label>
        <input type="text" name="price" id="price">
      </div>
      <div>
        <label for="created_at">Created At:</label>
        <input type="date" name="created_at" id="created_at">
      </div>
      <div>
        <label for="photo">Photo:</label>
        <input type="file" name="photo" id="photo">
      </div>
      <div>
        <label for="video">Video:</label>
        <input type="file" name="video" id="video">
      </div>
      <button type="submit">Add Product</button>
    </form>
  {% endblock %}
  <a href="{% url 'product_list' %}" class="btn">
    <button>返回商品列表首页</button>
  </a>
</body>
</html>

 

 

7 创建数据库、表结构和用户

python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser [admin/admin]

 

8 添加商品信息

要添加新商品信息,可以使用Django的后台管理界面或者在代码中手动创建Product模型实例.

在Django中添加新商品信息,包括名称、价格、描述、创建日期、照片和视频,创建了一个新的Product模型实例,设置了名称、描述、价格和创建日期,并将其保存到数据库中。此外,还使用了Django的文件存储API,将商品的照片和视频文件保存到了相应的字段中。

下面创建了一个新的Product模型实例,设置了名称、描述、价格和创建日期,并将其保存到数据库中

from datetime import datetime
from django.core.files import File
from .models import Product

# 创建一个新的商品实例
new_product = Product(
    name='New Product',
    description='This is a new product.',
    price=9.99,
    created_at=datetime.now()
)

# 设置商品的照片
with open('path/to/photo.jpg', 'rb') as photo_file:
    new_product.photo.save('photo.jpg', File(photo_file), save=True)

# 设置商品的视频
with open('path/to/video.mp4', 'rb') as video_file:
    new_product.video.save('video.mp4', File(video_file), save=True)

# 保存商品实例到数据库
new_product.save()

# 获取商品实例
new_product = Product.objects.get(id=1)

 

views.py


定义了一个add_product视图函数,用于展示添加新商品的表单页面,并处理表单提交的数据。在表单提交时,从request对象中获取表单数据,并创建一个新的Product模型实例,将表单数据设置为实例的属性值,并将实例保存到数据库中。最后,重定向到商品列表页面。在GET请求时,展示包含表单的HTML页面。

from datetime import datetime
from django.shortcuts import render, redirect
from .models import Product

def add_product(request):
    if request.method == 'POST':
        # 获取表单数据
        name = request.POST.get('name')
        description = request.POST.get('description')
        price = request.POST.get('price')
        created_at = request.POST.get('created_at')
        photo = request.FILES.get('photo')
        video = request.FILES.get('video')

        # 创建一个新的商品实例
        new_product = Product(
            name=name,
            description=description,
            price=price,
            created_at=created_at,
            photo=photo,
            video=video
        )

        # 保存商品实例到数据库
        new_product.save()

        # 重定向到商品列表页面
        return redirect('product_list')

    # 渲染添加商品表单页面
    return render(request, 'product_form.html')

 

 

9 查看商品信息

配置视图views.py

#查看商品列表
from django.shortcuts import render
from .models import Product

#查询了数据库中的所有Product模型实例,并将它们传递给名为product_list.html的模板文件进行展示。
# 在模板文件中,可以使用Django模板语言来访问这些Product模型实例的属性,例如名称、价格、描述、照片等。
def product_list(request):
    # 查询所有商品实例
    products = Product.objects.all()
    # 渲染商品列表模板,并传递products变量
    return render(request, 'product_list.html', {'products': products})

 

配置路由urls.py

from django.contrib import admin
from django.urls import path
from goods.views import product_list, product_detail,add_product


urlpatterns = [
    path('admin/', admin.site.urls),
    # path('', product_list, name='product_list'),
    path('<int:pk>/', product_detail, name='product_detail'),
    path('add_product/', add_product, name='add_product'),
    path('products/', product_list, name='product_list'),
]

 

配置图片路由

Django项目的urls.py文件中定义一个名为product_photos的URL路由,并将其映射到MEDIA_ROOT指定的媒体目录。
# 并将其映射到你的媒体目录product_photos。http://localhost:8000/product_photos/flows.jpg
#这个路由只在DEBUG模式下生效.因为在生产环境中,需要使用其他的方式来处理媒体文件

from django.contrib import admin
from django.urls import path
from goods.views import product_list, product_detail,add_product


urlpatterns = [
    path('admin/', admin.site.urls),
    # path('', product_list, name='product_list'),
    path('<int:pk>/', product_detail, name='product_detail'),
    path('add_product/', add_product, name='add_product'),
    path('products/', product_list, name='product_list'),
]
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path

if settings.DEBUG:  # 只在DEBUG模式下使用
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

10 添加视频及播放功能

定义模型添加表字段 models.py

### ###goods_service/goods/models.py
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)
    photo = models.ImageField(upload_to='product_photos/', blank=True)
    video = models.FileField(upload_to='product_videos/', blank=True)

    def __str__(self):
        return self.name

 

添加视频及播放功能

定义模型添加表字段 models.py

### ###goods_service/goods/models.py
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)
    # created_at = models.DateTimeField(auto_now_add=True, format='%Y-%m-%d')
    photo = models.ImageField(upload_to='product_photos/', blank=True)
    # category = models.ForeignKey('Category', on_delete=models.CASCADE, related_name='products')
    video = models.FileField(upload_to='product_videos/', blank=True)

    def __str__(self):
        return self.name

配置视图

### ### goods_service/goods/views.py

from django.shortcuts import render, redirect
from .models import Product

# 定义一个视图函数,用于处理添加商品信息的请求
def add_product(request):
    if request.method == 'POST':
        # 获取表单数据
        name = request.POST.get('name')
        description = request.POST.get('description')
        price = request.POST.get('price')
        created_at = request.POST.get('created_at')
        photo = request.FILES.get('photo')
        video = request.FILES.get('video')

        # 创建一个新的商品实例
        new_product = Product(
            name=name,
            description=description,
            price=price,
            created_at=created_at,
            photo=photo,
            video=video,
        )

        # 保存商品实例到数据库
        new_product.save()

        # 重定向到商品列表页面
        return redirect('product_list')

    # 渲染添加商品表单页面
    return render(request, 'product_form.html')

数据迁移和表字段添加

python manage.py makemigrations
python manage.py migrate

 

模版引用配置

product_list.html 视频播放配置

使视频元素相对于其包含元素的中心位置垂直和水平居中。请注意,这种方法假定包含视频的元素具有相对或绝对定位。如果您的包含元素没有定位,则此方法可能无法正常工作。

 

 

</style>
    video {
      position: absolute;
      top: 50%;
      height: 50px;
      left: 50%;
      transform: translate(-50%, -50%);
    }
</style>
<body>
  <video controls>
    <source src="/product_videos/1.mp4" type="video/mp4">
  </video>
</body>


----- 视频居中存放---
<style>
    video {
      position: relative;
      width: 60%;
      height: 600px;
      display: flex;
      justify-content: center;
      align-items: center;
      top: 50px;
    }
    .video video {
      display: block;
      margin: 0 auto;
    }
 </style>
<div class="video">
    <video controls>
      <source src="/product_videos/2.mp4" type="video/mp4">
    </video>
  </div>