Hello.
Long time django user here.
Over the year, I found myself writing again and again, from projects to projects, a PastDatetimeValidator (e.g for birth date, or generally thing that happened) and FuturDateTimeValidator (anything booking related, that don’t make sense to be in the past). I need these two all the time, and recently I found myself even needed them through django-rest-framework.
I would love to have these two built-in into django. Having the built into django would also help tremendously regarding localisation, having them correctly translated from the start.
If I have core developers greenlight, I am willing to make the pull request.
Cheers.
Hello @deronnax,
I’m not sure if you saw it, but there was a related ticket opened some time ago for this request: #35377 (Add past and future validators for Date and DateTime fields) – Django.
If there’s strong consensus around this feature, we could consider adding it. However, there was a prior discussion on the old mailing list where the idea was previously rejected.
@steering_council: any thoughts? Assuming these are three distinct users (the mailing list post, the ticket reporter, and this forum thread), there does seem to be growing interest. Personally, I think the complexity around timezones and related settings could benefit from a solid, tested solution in Django itself.
Would this be a candidate for a third-party package? That would allow the code (and tests and docs) to jell before adding it to core.
Hi @nessita thanks for the ping.
I think I agree with Tim, Jani, Josh, and Aymeric on the mailing list that this would be better suited to a third-party package.
I’m not really sure I don’t prefer the simple Boolean check to the named validator, if I’m honest.
This was the gist for the implementation from the mailing list post:
Noting Aymeric’s comment about preferring duck-typing, these are simple to implement and customise to individual needs.
I agree, this is such a small piece of logic that it’s not worth putting in the framework. It’s barely more than the example validator in the docs. Also, as shown in the explosion of options in the source Carlton linked, there’s an explosion of options between date
/datetime
support and inclusivity/exclusivity of the current day.
I think I agree with Tim, Jani, Josh, and Aymeric on the mailing list that this would be better suited to a third-party package
And still in 10 years, no third-party package managed to make it (successfuly I mean. You can find several abandonned django-datetime-validator on PyPI). So let’s acknowledge that this approach did not - and won’t - bring a solution.
If you are so bent on not integrate it, what about a small django-validator package endorsed by the django organisation (much more work and brainload to me than just integrating the 50 lines of the validator in the framework, but you do you).
I agree, this is such a small piece of logic that it’s not worth putting in the framework. It’s barely more than the example validator in the docs
The reference implementation promoted by @carltongibson in his above answer is 72 lines, 70 lines more than the 2 lines exemple to link to. So I think that even the django core community doesn’t have a clear, well defined picture about the subject
Currently, if I sum up well, the only clear rationale I can retrieve from the arguments is : “it is not used by another part of the framework, so it is not worthy being included”.
You seem cross. Everybody is acting in good faith, and it’s important to maintain a friendly environment.
The lack of an established package, especially ten years later, implies a lack of demand.
From my perspective these are trivial validators at the project level, where folks can handle just the case they’re interested in, and not worry about generalising. (As I said, I’d likely prefer the Boolean cases anyway to a named validator here, but that’s just my eye)
The bottom line is we can’t include everything (by a long way) so we have to say no to a lot to keep the core maintainable. An extra validator adds close to nothing but that all adds up. So same as with (e.g.) template tags or database functions, there’s a point where it’s not worth adding.
Sorry if that’s not what you wanted to hear.
Sorry for the tone. No, I am not crossed, I just tried to make things move.
Thank you for your valuable inputs
Nobody is against making it in to a plugin or adding to a existing active related plugin.
Obviously, there are 1000s of scenarios in the world, that would require 1000s of validation logic functions. It wouldn’t be wise to put them all into the core. But they all can make their way in to a beautiful package. So, everyone is happy and can reuse the code.
I’d like to have well tested options here as well. Looking at the list of validators that exist in Django core today, it’s really just what the framework needs. It doesn’t appear to be the core logic for applications’ business logic.
I think starting with a third-party package is the correct route here.
That’s not quite how things work. If you adopt one or create one, then talk about it, it’ll pick up traction. Package adoption is a problem in the Django community and the steering council is looking to help bridge that, but it’ll be slow. That said, you can probably get pretty far by posting about it, bringing it up on social media, then slowly adding to it, and writing more.
It’s always a fair amount of work for everyone. If this were just added to the framework, people may or may not find out about it. The adoption would be low until someone started talking about it. By asking a person to create the third-party library, helps that start earlier. All the content that gets created to keep a third-party package relevant is very beneficial to the community itself. It’s not wasted time and effort to get something into Django core, because that’s not the goal. The goal is to make the Django eco-system better.
One side question please: How would a validator like this be dealt with when it is involved in test code that is time dependent?
I’m aware of mocking but have never felt very comfortable with it. Also I’ve never seen it mentioned in the Django docs. My personal solution is to replace all usage of datetime.now()
with this:
def getDateToday():
if settings.FAKE_DATETIME_FOR_TESTS:
return settings.FAKE_DATETIME_FOR_TESTS.date()
return date.today()
def getDatetimeNow():
if settings.FAKE_DATETIME_FOR_TESTS:
return settings.FAKE_DATETIME_FOR_TESTS
return datetime.now()
but I wonder how this can be done better, that is, how everyone else is doing this?
The main problem with something like this is that time moves and validators like these can only be used at the form and not the model level. When you use a FutureDateValidator
, all historic records will necessarily be invalid. That may be what you want, but it could be troublesome to explain.
For the booking example you’d probably want to enforce starts_at > confirmed_at
or something like that, not starts_at > now()
, which requires model-level validation and cannot be enforced at the field level.
My opinion: The simple implementation can easily live at the project level, the more complete implementation has the potential to be more complex than we want and still not cover all use cases.
I’ve been using freezegun · PyPI (earlier) and GitHub - adamchainz/time-machine: Travel through time in your tests. (present) for unit testing. I’d recommend the latter, but both have worked well for me in the past. It’s probably a good idea to rely on a library instead of doing the mock yourself in this case.