-
-
Notifications
You must be signed in to change notification settings - Fork 267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proof of concept for a loosely defined date field #2691
base: main
Are you sure you want to change the base?
Conversation
You can change type and contents at the same time with USING:
I'm a bit wary of ditching the date type field when in many cases it is a date being entered in the field. I would look to allow the input of the published date without day or month. When written to the database replace anything missing with 01 and set a flag in another column. Then when displaying the date extract the required elements of the date (e.g. just year) based on this flag. That way you lose none of the benefits of storing as a date (like extracting the parts you want to render with existing SQL functions; use of sort, comparison etc). Just my initial thoughts. May be flawed. |
Yeah I need to understand more how we query those date fields, the main benefits for keeping them as date fields mostly revolve around querying, either with |
The ideal requirements on ordering could also help arguing one way or another. For example, should the ascending order be:
Or the other way around, ordering less precise dates at the end:
If we think the second case is more intuitive then your proposed solution @marcusyoung would make more sense, with a small twist: |
You'll also need to consider what happens on import too, with the date coming from OpenLibrary etc. |
May also be a problem with instances being on different versions if this field is inconsistent between databases? |
OpenLibrary is even more flexible, either it's just a year (like mentioned here), or if a book has a precise publishing date (this specific audiobook edition) it transmits it as "Mar 01, 2021".
Yes! That is a point that we'll have to consider. I'll add it above to not forget. |
I added a proof of concept with @marcusyoung's proposed solution which stores an extra field for each date, i.e. Besides the extra fields in the model, we can get away with just overriding the form's On a form render we:
On a form submit we:
The (ugly) implementation is in this commit: 5c9e318 Generally, I like this approach better. We can still use the date fields for ordering, Curious to know what you think of these two approaches @mouse-reeve? Feel free to compare the two commits in this PR. |
We could perhaps avoid the additional AP fields because partial serialization in formats like YYYY and YYYY-MM are backwards-compatible with the current use of (To be clear, I'm only talking about network-transmitted data here.) Say such code is released in v0.7. Then, upon an incoming date like '2023':
P.S.: While I'm commenting, I do like the idea of a custom (¹) As an instance maintainer, I would love if the migration either defaulted, or allowed me to pick, "set precision = year if day = month = 1". |
I submitted #3059 for review, which reuses every possible field and form, in order to keep backwards compatibility. Turns out Django forms already support serializing partial (though possibly invalid) dates: they do it replacing |
This could be a potential solution for #743.
Essentially this adds two new classes:
LooseDate
value object withyear
(required),month
(optional), andday
(optional)LooseDateField
for storingLooseDate
value objects in the databaseThings to note:
LooseDate
is validating that it's a valid date by replacing optionally missing values for month and day with 1, and then validating the dateYYYY-MM-DD
format, missing values for month and day are represented as00
, so the different permutations are"2023-02-22"
,"2023-02-00"
,"2023-00-00"
Things that I still need to try:
ORDER BY published_date
work with this new field. Could potentially work out of the box with string ordering?Things that are outstanding for proper implementation of this:
What do you all think about this? Anything I missed that I should check?
The screenshot isn't really proof 😅 but this actually does work 🎉
Alternative solution as proposed by @marcusyoung
Instead of using a string field, we could keep using a date (it's actually a datetime) field, and fill in the missing parts with 1. In addition to this, we have a second field which defines the precision.
For a date like Feb 2023 we would store:
published_date = "2023-02-01"
- really"2023-02-01 00:00:00Z"
because it's a datetimepublished_date_precision = "month"
I like this approach because it allows us to continue using the datefield in queries in
WHERE
clauses or ordering.It would even allow us to decide if a less precise date should be ordered after a more precise one, or the other way around.
For example: