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

Django中如何将两个模型字段拼接后赋值给第三个模型字段

Django配送预约系统编号生成实现方案

现有代码问题修正

首先需要先修复现有代码的两处错误,否则功能无法正常运行:

  • forms.py中BookingForm的Meta.fields字段配置错误:你写的booking_date、booking_time和模型中定义的delivery_date、delivery_time字段名不匹配,需要同步修改。
  • 不要把booking_number的赋值逻辑放在__str__方法中,该方法仅用于返回实例的字符串标识,不会在数据入库时触发,赋值逻辑需要放在模型的save()方法中。

核心功能实现

你需要重写Booking模型的save方法,在数据写入数据库前自动拼接日期时间生成预约编号,修改后的完整models.py代码如下:

from django.db import models
from django.utils import timezone
from django.urls import reverse
import datetime as dt
from django.contrib.auth.models import User


class Booking(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE)
    qty_plts = models.PositiveSmallIntegerField(default=1)
    cbm = models.PositiveSmallIntegerField(default=1)
    # 注意这里default不要加括号,否则会固定为项目启动时间
    created_date = models.DateTimeField(default=timezone.now)
    delivery_date = models.DateTimeField()
    delivery_time = models.TimeField()
    booking_number = models.CharField(max_length=50, unique=True)

    def save(self, *args, **kwargs):
        # 拼接配送日期和时间为完整datetime对象
        full_datetime = dt.datetime.combine(self.delivery_date.date(), self.delivery_time)
        # 按DDMMYYYYHHMM格式生成编号,要带分隔符就改成"%d-%m-%Y-%H-%M"
        self.booking_number = full_datetime.strftime("%d%m%Y%H%M")
        super().save(*args, **kwargs)

    def __str__(self):
        return self.booking_number

    def get_absolute_url(self):
        return reverse("booking_detail",kwargs={'pk':self.pk}) 

修正后的forms.py代码如下:

from django import forms
from bookmyslot.models import Booking
from bootstrap_datepicker_plus import DatePickerInput
import datetime as dt

HOUR_CHOICES = [(dt.time(hour=x), '{:02d}:00'.format(x)) for x in range(7, 13)]

class BookingForm(forms.ModelForm):

    class Meta:
        model = Booking
        # 修正字段名匹配模型定义
        fields = ('qty_plts','cbm','delivery_date','delivery_time')
        widgets = {'delivery_date':DatePickerInput(options={"daysOfWeekDisabled":[0,6]}),
                    'delivery_time':forms.Select(choices=HOUR_CHOICES)}

预约编号唯一性保障

如果你的业务允许同一时段多个用户预约,直接按上述代码生成的编号会重复,你可以选择两种方案解决:

  • 方案1:给delivery_date和delivery_time添加联合唯一约束,限制同一时段只能有一个预约,天然保证编号唯一,只需要在Booking模型中添加如下配置即可:
    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['delivery_date', 'delivery_time'], name='unique_delivery_slot')
        ]
    
  • 方案2:保留同一时段多预约的能力,在生成编号时追加用户ID后缀,修改save方法中的编号生成逻辑即可:
    self.booking_number = f"{full_datetime.strftime('%d%m%Y%H%M')}-{self.user.id}"
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 02:45:04