#python #django
#python #django
Вопрос:
Это довольно странный вопрос
class Post(models.Model):
name = models.CharField(max_length=200)
class PostKey(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
def __str__(self):
return self.post.name " | " self.name
Я пытаюсь использовать детальное представление таким образом, чтобы оно отображало детали Post
модели, а также показывало список PostKey
(не мог придумать никакого другого имени), который имеет тот же идентификатор, post.id
что и . Я создал отношение » один ко многим » с Post
использованием модели ForeignKey
.
Вот мое мнение:
from django.shortcuts import render
from django.views.generic import TemplateView, DetailView
from .models import Post, PostKey
class TestView(TemplateView):
template_name = "test.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["posts"] = Post.objects.all()
return context
class PostDetailView(DetailView, Post):
template_name = "test2.html"
model = Post
def get_context_data(self, **kwargs ):
context = super().get_context_data( **kwargs)
context['details'] = PostKey.objects.filter(id= Post.id)
return context
но когда я запускаю этот код, он показывает мне что-то вроде этого:
TypeError at /post/2
Field 'id' expected a number but got <django.db.models.query_utils.DeferredAttribute object at 0x03F88478>.
Я пытался добавить int(Post.id)
, но это все равно не работает.
Вот шаблон, который визуализируется для приведенного выше представления.
{% for detail in details %}
{{detail.name}}
{% endfor %}
Любая помощь будет оценена
Комментарии:
1. @WillemVanOnsem помогите мне с этим
Ответ №1:
Вы фильтруете с помощью:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['details'] = PostKey.objects.filter(post=self.object)
return context
или с помощью:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['details'] = self.object.postkey_set.all()
return context
Комментарии:
1. что означает self.object, я этого не понимаю
2. извините, если я вас расстраиваю, ребята, я всего лишь начинающий разработчик, и меня смущает так много вещей
Ответ №2:
Код, который вы написали
context['details'] = PostKey.objects.filter(id= Post.id)
не работает, потому Post
что это класс модели, а не экземпляр модели, что означает, что Post.id
это определение поля модели для класса, а не значение Post
экземпляра, который вы ищете; экземпляр в DetailView
находится внутри self.object
.
Кроме того, вы, вероятно, захотите выполнить поиск во всех PostKey
экземплярах, которые self.object
являются родительскими, а не в тех, которые имеют тот же идентификатор, что и родительский; вам нужно фильтровать с помощью поля PostKey.post
(которое является внешним ключом для родительского Post
).
Вероятно, вам нужно использовать Post
экземпляр (in self.object
) для фильтрации всех PostKey
объектов, которые self.object
являются их родительскими.
class PostDetailView(DetailView):
template_name = "test2.html"
model = Post
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['details'] = PostKey.objects.filter(post=self.object)
# or also the way @WillemVanOnsem suggested in his answer
# context['details'] = self.object.postkey_set.all()
return context
И код шаблона, который вы показали, кажется прекрасным:
{% for det in details %}
{{ det.name }}
{{ det }} <!-- this will use method PostKey.__str__() -->
{% endfor %}
Кроме того, почему ваш класс наследуется от Post
(у вас есть class PostDetailView(DetailView, Post):
)?
Это не кажется правильным, DetailView
в этом случае оно должно просто наследоваться.
Комментарии:
1. ваш ответ имеет смысл, и я собираюсь попробовать его сейчас, когда у меня ничего не получалось, я просто сделал
PostDetailView
inherit from Post, чтобы попробовать другой подход2. можете ли вы также помочь мне показать это в шаблоне
3. @Flamiooo Ваш код шаблона выглядит нормально; повторение
details
и отображение каждой детали должны работать с кодом шаблона, который вы показали.4. это работает, и я, наконец, могу работать над реальным проектом