Obecnie mam wiele obiektów Pythona w moim kodzie, podobnych do następujących:
class MyClass():
def __init__(self, name, friends):
self.myName = name
self.myFriends = [str(x) for x in friends]
Teraz chcę przekształcić to w model Django, w którym self.myName to pole tekstowe, a self.myFriends to lista ciągów.
from django.db import models
class myDjangoModelClass():
myName = models.CharField(max_length=64)
myFriends = ??? # what goes here?
Ponieważ lista jest tak powszechną strukturą danych w Pythonie, spodziewałem się, że będzie dla niej pole modelu Django. Wiem, że mogę użyć relacji ManyToMany lub OneToMany, ale miałem nadzieję uniknąć tego dodatkowego pośrednictwa w kodzie.
Edytować:
Dodałem to pokrewne pytanie , które może się przydać.
python
django
django-models
smucić
źródło
źródło
Odpowiedzi:
Czy ta relacja nie byłaby lepiej wyrażona jako relacja klucza obcego jeden do wielu z
Friends
tabelą? Rozumiem, żemyFriends
to tylko łańcuchy, ale myślę, że lepszym projektem byłoby utworzenieFriend
modelu iMyClass
zawarcie powiązania klucza obcego z wynikową tabelą.źródło
„Przedwczesna optymalizacja jest źródłem wszelkiego zła”.
Mając to na uwadze, zróbmy to! Gdy Twoje aplikacje osiągną określony punkt, denormalizacja danych jest bardzo powszechna. Wykonane poprawnie, może zaoszczędzić wiele kosztownych wyszukiwań w bazie danych, kosztem nieco większego uporządkowania.
Aby zwrócić
list
imiona znajomych, będziemy musieli utworzyć niestandardową klasę Django Field, która po uzyskaniu dostępu zwróci listę.David Cramer opublikował na swoim blogu przewodnik dotyczący tworzenia SeperatedValueField. Oto kod:
Logika tego kodu dotyczy serializacji i deserializacji wartości z bazy danych do języka Python i odwrotnie. Teraz możesz łatwo importować i używać naszego pola niestandardowego w klasie modelu:
źródło
my_vals = SeparatedValuesField(blank=True, default="")
ale otrzymuję IntegrityError z powodu wartości NULL. Czy domyślny argument nie jest poprawnie przekazywany?to_python
nie jest już wywoływana podczas odczytu. Tak więc, aby to zadziałało, musisz dodać:def from_db_value(self, value, expression, connection, context): return self.to_python(value)
Prostym sposobem na przechowywanie listy w Django jest po prostu przekonwertowanie jej na ciąg JSON, a następnie zapisanie go jako tekstu w modelu. Następnie możesz pobrać listę, konwertując ciąg (JSON) z powrotem na listę Pythona. Oto jak:
„Lista” byłaby przechowywana w Twoim modelu Django w następujący sposób:
Twój widok / kod kontrolera:
Przechowywanie listy w bazie danych:
Pobieranie listy z bazy danych:
Koncepcyjnie, oto co się dzieje:
źródło
Jeśli używasz Django> = 1.9 z Postgresem, możesz skorzystać z zalet ArrayField
Możliwe jest również zagnieżdżenie pól tablicowych:
Jak wspomniał @ thane-brimhall, możliwe jest również bezpośrednie zapytanie o elementy. Odniesienie do dokumentacji
źródło
Ponieważ jest to stare pytanie, a techniki Django musiały się znacznie zmienić od tamtego czasu, ta odpowiedź odzwierciedla wersję 1.4 Django i najprawdopodobniej ma zastosowanie do wersji 1.5.
Django domyślnie używa relacyjnych baz danych; powinieneś z nich skorzystać. Mapuj przyjaźnie do relacji w bazie danych (ograniczenia klucza obcego) za pomocą ManyToManyField. Dzięki temu możesz używać RelatedManager do list znajomych, które używają inteligentnych zestawów zapytań. Możesz użyć wszystkich dostępnych metod, takich jak
filter
lubvalues_list
.Korzystanie z
ManyToManyField
relacji i właściwości:Możesz uzyskać dostęp do listy znajomych użytkownika w ten sposób:
Zauważ jednak, że te relacje są symetryczne: jeśli Józef jest przyjacielem Boba, to Bob jest przyjacielem Josepha.
źródło
źródło
Pamiętaj, że to ostatecznie musi trafić do relacyjnej bazy danych. Tak więc używanie relacji jest naprawdę powszechnym sposobem rozwiązania tego problemu. Jeśli absolutnie nalegasz na przechowywanie listy w samym obiekcie, możesz na przykład rozdzielić ją przecinkami i przechowywać w ciągu, a następnie udostępnić funkcje akcesory, które podzielą ciąg na listę. Dzięki temu będziesz ograniczony do maksymalnej liczby ciągów i utracisz wydajne zapytania.
źródło
Jeśli używasz postgres, możesz użyć czegoś takiego:
jeśli potrzebujesz więcej informacji, możesz przeczytać w poniższym linku: https://docs.djangoproject.com/pt-br/1.9/ref/contrib/postgres/fields/
źródło
Możesz przechowywać praktycznie każdy obiekt za pomocą pola Django Pickle, ala ten fragment:
http://www.djangosnippets.org/snippets/513/
źródło
Przechowywanie listy ciągów w modelu Django:
i możesz to nazwać tak:
źródło
Moje rozwiązanie, może komuś pomoże:
źródło
Użycie relacji jeden do wielu (FK z klasy Friend do klasy nadrzędnej) sprawi, że Twoja aplikacja będzie bardziej skalowalna (ponieważ możesz w trywialny sposób rozszerzyć obiekt Friend o dodatkowe atrybuty poza prostą nazwą). A więc to najlepszy sposób
źródło