Разрешить вставку данных только после порогового значения длительности времени в django

У меня есть модель в Django с атрибутом DateTimeField. Я хочу запретить вставку новых данных в базу данных, если длительность между полем даты новых данных и последним полем даты в базе данных меньше некоторого порога длительности.

class MyModel(models.Model):

time_stamp = models.DateTimeField(default=timezone.now, null=True)

Когда я хочу вставить точку данных, скажем, сегодня, а последняя отметка времени в моей базе данных - вчера, и порог продолжительности составляет один месяц (эта операция не должна быть возможной).

Вы можете определить эту логику в ваших представлениях следующим образом:

from django.shortcuts import get_object_or_404
import datetime

def CreateNew(request, id):
    obj = get_object_or_404(MyModel, id = id) #Get the object from your database
    form = YourForm(request.POST or None, instance = obj) #create form instance to be rendered inside template

    diff = (timezone.now() - obj.time_stamp).total_seconds()
    threshold = datetime.timedelta(days=30).total_seconds()

    if diff < threshold: # Compare dates to check condition
        return HttpResponse('<h1>Not Allowed</h1>')
    elif form.is_valid(): # If condition is passed save form as you normally would
        form.instance.time_stamp = timezone.now() # Update time_stamp to current time
        form.save()
        return HttpResponseRedirect("/")

context = {
    'form': form
}
return render(request, "Your_template", context)

Если вы уверены, что это можно предотвратить более жестким способом, чем размещение логики защиты в представлении, то вместо проверки в представлении вы можете проверить в методе модели save.

def save( self, *args, **kwargs):

    diff = (timezone.now() - self.time_stamp).total_seconds()
    threshold = datetime.timedelta(days=30).total_seconds()

    if diff < threshold: # Compare dates to check condition

        # not certain ValueError is the best choice of exception
        raise ValueError( 
            f"Can't save because {diff} seconds since the previous save, the minimum is {theshold}"
        )
    super().save( *args, **kwargs)

Эту проверку все еще можно обойти, например, с помощью Django bulk_update, а также с помощью необработанного SQL. Некоторые базы данных могут позволить вам поместить проверку в саму базу данных.

Недостатком является то, что исправление ошибок с помощью (например) Django Admin может стать затруднительным. В этом случае вы можете программно обойти проверку, предварительно сбросив временную метку.

Вернуться на верх