You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python/Django中如何创建支持多服务及对应定价的用户关联模型

Django模型设计方案

核心设计思路

你的需求核心是「单个用户可关联多项独立服务,每项服务对应独立定价」,采用一对多关联的表结构即可实现,符合数据库范式,后续扩展灵活度高。

完整模型代码

from django.db import models
# 如果你用自定义用户模型,替换成自己的用户模型引入路径
from django.contrib.auth.models import User

class Service(models.Model):
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name="published_services",
        verbose_name="所属用户"
    )
    name = models.CharField(max_length=120, verbose_name="服务名称")
    # 金额统一用DecimalField避免浮点数精度丢失问题
    price = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name="服务定价",
        help_text="可自行约定单位,如人民币元/次、人民币元/小时等"
    )
    # 以下为可选扩展字段,可按需删除
    description = models.TextField(blank=True, null=True, verbose_name="服务描述")
    is_active = models.BooleanField(default=True, verbose_name="是否上架")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="发布时间")

    def __str__(self):
        return f"{self.user.username} 的服务:{self.name}({self.price})"

设计说明

  • 通过ForeignKey关联用户表,实现一个用户对应多条服务记录的一对多关系,满足多服务提交的需求
  • on_delete=models.CASCADE配置代表用户删除时,对应发布的服务也会同步删除,你也可以根据业务需求换成PROTECT/SET_NULL等其他删除策略
  • 定价字段选择DecimalField而非FloatField,避免浮点数运算、存储时的精度丢失问题,更适合金额类数据存储

多服务批量提交表单实现

要支持用户在单个页面提交多项服务,可直接使用Django内置的Formset功能:

# forms.py
from django.forms import modelformset_factory
from .models import Service

# extra参数控制默认展示的空表单数量,用户可自行增减
ServiceFormSet = modelformset_factory(
    Service,
    fields=("name", "price", "description"),
    extra=3,
    can_delete=True # 加这个参数支持用户删除不需要的空表单
)

视图层处理逻辑示例:

# views.py
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import ServiceFormSet

@login_required
def publish_services(request):
    if request.method == "POST":
        # queryset设为空代表不加载已有服务,仅提交新服务
        formset = ServiceFormSet(request.POST, queryset=Service.objects.none())
        if formset.is_valid():
            services = formset.save(commit=False)
            # 给所有新提交的服务绑定当前登录用户
            for service in services:
                service.user = request.user
                service.save()
            # 保存成功后跳转到服务列表页,路径可自行替换
            return redirect("service_list")
    else:
        formset = ServiceFormSet(queryset=Service.objects.none())
    
    return render(request, "publish_services.html", {"formset": formset})

模板中直接渲染formset即可,无需额外自定义复杂逻辑。


内容的提问来源于stack exchange,提问作者Akylson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 05:27:03