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
相关产品推荐
相关产品推荐

