Po pierwsze, dziękuję za wszystkie odpowiedzi. Żaden z nich nie był dobrym rozwiązaniem mojego problemu, ale na obronę dodam, że nie podałem wszystkich wymagań. Ale każdy z nich pomaga mi pomyśleć o moim problemie, a niektóre z twoich pomysłów są częścią mojego ostatecznego rozwiązania.
Więc moim ostatecznym rozwiązaniem, po stronie DB, jest użycie varchar pole (ograniczone do 10 znaków) i przechowywanie w nim daty w postaci ciągu w formacie ISO (RRRR-MM-DD) z 00 dla miesiąca i dnia, gdy nie ma miesiąca i/lub dnia (np. data w MySQL). W ten sposób to pole może współpracować z dowolnymi bazami danych, dane mogą być odczytywane, rozumiene i edytowane bezpośrednio i łatwo przez człowieka za pomocą prostego klienta (takiego jak klient mysql, phpmyadmin itp.). To był wymóg. Można go również wyeksportować do Excela/CSV bez konwersji itp. Wadą jest to, że format nie jest wymuszany (z wyjątkiem Django). Ktoś mógłby napisać „nie randkę” lub popełnij błąd w formacie, a DB go zaakceptuje (jeśli masz pomysł na ten problem...).
W ten sposób można również wykonać wszystkie specjalne zapytania z datą pole stosunkowo łatwo. Dla zapytań z WHERE:<,>, <=,>=i =działają bezpośrednio. Zapytania IN i BETWEEN również działają bezpośrednio. W przypadku zapytania według dnia lub miesiąca wystarczy zrobić to za pomocą WYCIĄGU (DZIEŃ|MIESIĄC...). Zlecanie pracy również bezpośrednio. Myślę więc, że obejmuje wszystkie potrzeby związane z zapytaniami i w większości bez komplikacji.
Po stronie Django zrobiłem 2 rzeczy. Najpierw utworzyłem PartialDate
obiekt, który wygląda głównie jak datetime.date
ale wspierająca data bez miesiąca i/lub dnia. Wewnątrz tego obiektu do zachowania daty używam obiektu datetime.datetime. Używam godzin i minut jako flagi, która informuje, czy miesiąc i dzień są prawidłowe, gdy są ustawione na 1. To ten sam pomysł, co steveha zaproponować ale z inną realizacją (i tylko po stronie klienta). Korzystanie z datetime.datetime
obiekt daje mi wiele fajnych funkcji do pracy z datami (walidacja, porównanie itp.).
Po drugie, utworzyłem PartialDateField
które głównie zajmują się konwersją między PartialDate
obiekt i bazę danych.
Jak dotąd działa całkiem dobrze (w większości skończyłem moje obszerne testy jednostkowe).