【问题标题】:Allow fields to be valid or non-valid based on DateField ranges根据日期字段范围允许字段有效或无效
【发布时间】:2020-07-05 17:06:42
【问题描述】:

我有一个名为 products 的模型,如下所示:

class Product(models.Model):

    name = models.CharField(max_length=200, null=True)
    r_price = models.FloatField(null=True)
    d_price = models.FloatField(null=True, blank=True, default='')
    start_date = models.DateField(null=True, blank=True, default='')
    end_date = models.DateField(null=True, blank=True, default='')

我的模型中的日期字段称为 start_date 和 end_date。

我的意图是如果当前日期在 start_date 和 end_date 的范围内,d_price 将是有效的(在其表单内提交值)。

如果当前日期不在 start_date 和 end_date 的范围内,或者如果当前日期超过了结束日期,则 r_price 字段将有效地获取要提交的值,并且 d_price 将不再有效。

参见下文,了解基于模型创建和更新实例时的视图。

创建实例时 -

def NewProductProfile(request):
    form = CreateProductForm()
    if request.method == 'POST':
        form = CreateProductForm(request.POST or None)
        if form.is_valid():
            form.save()
            return redirect('product_list')
    return render(request, 'accounts/new_product_profile.html', {'form': form})

更新实例时 -

def EditProduct(request, pk):

    product = Product.objects.get(id=pk)
    form = ProductForm(instance=product)
    if request.method == 'POST':
        form = ProductForm(request.POST, instance=product)
        if form.is_valid():
            form.save()
            return redirect('product_list')

    return render(request, 'accounts/edit_product_profile.html', {'form': form})

有效,表示提及的字段将被激活。

例如,如果当前日期在start_date和end_date的范围内,则在提交表单时更新实例。

r_price 中的 Float 值在其表单中提交时将不考虑也不保存在数据库中,而只会考虑 d_price(如果当前日期在 start_date 和 end_date 的范围内)。

因此,如果当前日期不在 start_date 和 end_date 之间,则不会保存 d_price 中的 float 值,但在通过表单提交时更新产品实例时会将 r_price 保存在数据库中。

start_date 和 end_date 字段将由预期用户手动输入。

这将如何实施?

【问题讨论】:

  • “d_price/r_price 对取值有效”是什么意思?
  • 为了清楚起见,我已经编辑了帖子。

标签: python django django-views


【解决方案1】:

Model.clean()

此方法应用于提供自定义模型验证,以及 如果需要,修改模型上的属性。例如,你可以 使用它自动为字段提供值,或执行 需要访问多个字段的验证。

你应该按照你的逻辑做一些事情。

class Product(models.Model):

    name = models.CharField(max_length=200, null=True)
    r_price = models.FloatField(null=True)
    d_price = models.FloatField(null=True, blank=True, default='')
    start_date = models.DateField(null=True, blank=True, default='')
    end_date = models.DateField(null=True, blank=True, default='')


    def clean(self):
        if self.start_date < datetime.now() < self.end_date:
            self.r_price = None

        elif self.end_date < datetime.now():
            self.d_price = None

注意:模型实例保存时不会调用模型清理方法,因此您必须在模型保存方法中手动调用它。

https://docs.djangoproject.com/en/3.0/ref/models/instances/#django.db.models.Model.clean

【讨论】:

  • 似乎不起作用,因为我收到错误消息,即“模块 'datetime' 没有属性 'now'”。我是否有可能拥有另一个具有 auto_now_add=True 的 DateTimeField。
  • @kamcoder 你需要像这样添加导入from datetime import datetime
  • 是的,但现在我收到类似这样的错误,“'NoneType' 和 'datetime.datetime' 的实例之间不支持'
  • 您需要相应地处理它。在帖子中,您提到 end_date 和 start_date 字段将由预期用户手动输入,但这里它们是 None
  • 是的,我已经手动输入了 d_price、start_date 和 end_date 的值进行测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 2020-05-23
  • 2022-01-01
  • 2016-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多