首页 > 解决方案 > 根据 DateField 范围允许字段有效或无效

问题描述

我有一个名为 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 中的浮点值,但在通过表单提交时更新产品实例时将 r_price 保存在数据库中。

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

这将如何实施?

标签: pythondjangodjango-views

解决方案


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


推荐阅读