Omawiany błąd jest spowodowany próbą uzyskania dostępu do Manager
modelu za pośrednictwem instancji modelu. Użyłeś dolne liter nazwy klas. To sprawia, że trudno powiedzieć, czy błąd jest spowodowany przez instancję uzyskującą dostęp do pliku, Manager
czy nie. Ponieważ inne scenariusze, które mogą powodować ten błąd, są nieznane, wychodzę z założenia, że w jakiś sposób pomieszałeś topic
zmienną, tak że w końcu wskażesz wystąpienie topic
modelu zamiast klasy.
Ta linia jest winowajcą:
forum.topic_count = topic.objects.filter(forum = forum).count()
Musisz użyć:
forum.topic_count = Topic.objects.filter(forum = forum).count()
Co się dzieje? objects
jest Manager
dostępny na poziomie klasy, a nie dla instancji. Szczegółowe informacje można znaleźć w dokumentacji dotyczącej pobierania obiektów . Wycena pieniędzy:
Managers
są dostępne tylko za pośrednictwem klas modelu, a nie z instancji modelu, aby wymusić oddzielenie operacji „na poziomie tabeli” od operacji „na poziomie rekordu”.
(Podkreślenie dodane)
Aktualizacja
Zobacz komentarze @Daniel poniżej. Dobrym pomysłem jest (nie, MUSISZ: P) używać wielkich liter w nazwach klas. Na przykład Topic
zamiast topic
. Nazwy twoich klas powodują pewne zamieszanie, niezależnie od tego, czy odnosisz się do instancji, czy do klasy. Ponieważ Manager isn't accessible via <model> instances
jest bardzo specyficzny, jestem w stanie zaoferować rozwiązanie, błąd może nie zawsze być tak oczywisty.
topic
wydaje się, że jest to rzeczywista klasa modelu, a nie instancja zgodnie z dostarczonym przez niego kodem.Manager isn't accessible via Foo instances
jest możliwy tylko wtedy, gdy próbujesz uzyskać dostęp doManager
za pomocą instancji. Zobacz kod źródłowy: code.djangoproject.com/svn/django/trunk/django/db/models/…topic
jako zmiennej lokalnej instancji i usuwa odwołanie do klasy.topic.model_class().objects
topic.__class__.objects
. Wydaje się, żemodel_class()
wspomniane przez @Nimo powyżej nie działatopic.__class__.objects.get(id=topic_id)
źródło
__class__
działa lepiej dla metod w abstrakcyjnych modeli, jak również, gdy nie znamy rzeczywistej nazwy potomkiem klasy. W tej sytuacji użyłemself.__class__.objects.get
Dla django <1.10
topic._default_manager.get(id=topic_id)
Chociaż nie powinieneś tego używać w ten sposób. _Default_manager i _base_manager są prywatne, więc zaleca się ich używanie tylko wtedy, gdy jesteś w modelu tematu, na przykład gdy chcesz użyć menedżera w zastrzeżonej funkcji, powiedzmy:
class Topic(Model): . . . def related(self) "Returns the topics with similar starting names" return self._default_manager.filter(name__startswith=self.name) topic.related() #topic 'Milan wins' is related to: # ['Milan wins','Milan wins championship', 'Milan wins by one goal', ...]
źródło
topic.__class__.objects.get(id=topic_id)
.self.__class__.objects
działa sztuczka według innej odpowiedzi.Może być również spowodowane zbyt dużą parą parantez, np
ModelClass().objects.filter(...)
zamiast prawidłowego
ModelClass.objects.filter(...)
Zdarza mi się czasami, gdy bpython (lub IDE) automatycznie dodaje paranthezy.
Wynik jest oczywiście taki sam - zamiast klasy masz instancję.
źródło
gdyby topic był instancją ContentType (a nią nie jest), zadziałałoby:
topic.model_class().objects.filter(forum = forum)
źródło
model_class()
jest metodąContentType
modelu. Inne instancje modelu, w tymtopic
, nie mająmodel_class
metody.Właśnie miałem problem podobny do tego błędu. Patrząc wstecz na twój kod, wydaje się, że może to być również twój problem. Myślę, że Twoim problemem jest to, że nie ustawiono porównania „id” z „int (topic_id)” i topic_id.
def test(request, post_id): post = topic.objects.get(id = int(topic_id)) post.delete()
Zgaduję, że Twój kod powinien zawierać „post_id”, a nie „topic_id”
def test(request, post_id): post = topic.objects.get(id = int(post_id)) post.delete()
źródło