Django ma różne pola numeryczne dostępne do użycia w modelach, np. DecimalField i PositiveIntegerField . Chociaż to pierwsze można ograniczyć do liczby przechowywanych miejsc dziesiętnych i ogólnej liczby przechowywanych znaków, czy istnieje sposób, aby ograniczyć je do przechowywania tylko liczb z określonego zakresu, np. 0,0–5,0?
Jeśli to się nie uda, czy istnieje sposób, aby ograniczyć PositiveIntegerField do przechowywania, na przykład, tylko liczb do 50?
Aktualizacja: teraz, gdy Bug 6845 został zamknięty , to pytanie StackOverflow może być dyskusyjne. - sampablokuper
python
django
django-models
numbers
sampablokuper
źródło
źródło
Odpowiedzi:
Możesz także utworzyć niestandardowy typ pola modelu - zobacz http://docs.djangoproject.com/en/dev/howto/custom-model-fields/#howto-custom-model-fields
W takim przypadku można „dziedziczyć” z wbudowanej wartości IntegerField i przesłonić jej logikę walidacji.
Im więcej o tym myślę, tym zdaję sobie sprawę, jak przydatne byłoby to dla wielu aplikacji Django. Być może typ IntegerRangeField mógłby zostać przesłany jako łatka dla programistów Django, aby rozważyli dodanie do linii głównej.
To działa dla mnie:
Następnie w swojej klasie modelowej użyłbyś tego w następujący sposób (pole jest modułem, w którym umieściłeś powyższy kod):
LUB dla zakresu ujemnego i dodatniego (jak zakres oscylatora):
Byłoby naprawdę fajne, gdyby można go było wywołać za pomocą operatora zasięgu w ten sposób:
Ale wymagałoby to znacznie więcej kodu, ponieważ można określić parametr `` pomiń '' - zakres (1, 50, 2) - ciekawy pomysł ...
źródło
MinValueValidator(min_value) and MaxValueValidator(max_value)
przed wywołaniemsuper().__init__ ...
(snippet: gist.github.com/madneon/147159f46ed478c71d5ee4950a9d697d )Możesz użyć wbudowanych walidatorów Django -
Edycja : Pracując bezpośrednio z modelem, przed zapisaniem modelu należy wywołać metodę full_clean , aby uruchomić walidatory. Nie jest to wymagane podczas używania,
ModelForm
ponieważ formularze zrobią to automatycznie.źródło
null=True
iblank=True
działa zgodnie z oczekiwaniami. Pole jest opcjonalne i jeśli pozostanie puste, zostanie zapisane jako null.źródło
Miałem ten sam problem; oto moje rozwiązanie:
źródło
models.IntegerField(choices=[(i, i) for i in range(1, n)], blank=True)
Można to zrobić na dwa sposoby. Jednym z nich jest użycie walidacji formularza, aby nigdy nie pozwolić użytkownikowi wprowadzić żadnej liczby powyżej 50. Dokumenty walidacji formularzy .
Jeśli w proces nie jest zaangażowany żaden użytkownik lub nie używasz formularza do wprowadzania danych, musisz zastąpić
save
metodę modelu, aby zgłosić wyjątek lub ograniczyć dane trafiające do pola.źródło
Oto najlepsze rozwiązanie, jeśli potrzebujesz dodatkowej elastyczności i nie chcesz zmieniać pola modelu. Po prostu dodaj ten niestandardowy walidator:
I może być używany jako taki:
Te dwa parametry to max i min i dopuszczają wartości null. Możesz dostosować walidator, jeśli chcesz, usuwając zaznaczoną instrukcję if lub zmieniając pole tak, aby było puste = False, null = False w modelu. Będzie to oczywiście wymagało migracji.
Uwaga: Musiałem dodać walidator, ponieważ Django nie sprawdza zakresu na PositiveSmallIntegerField, zamiast tego tworzy smallint (w postgres) dla tego pola i otrzymujesz błąd DB, jeśli podana liczba jest poza zakresem.
Mam nadzieję, że to pomoże :) Więcej o walidatorach w Django .
PS. Swoją odpowiedź oparłem na BaseValidator w django.core.validators, ale wszystko jest inne poza kodem.
źródło