如何保存和显示与其他数据关联的DetailView数据

时间:2018-06-14 02:16:56

标签: django django-models django-forms django-templates django-views

我非常感谢任何帮助。我有以下代码:

views.py:

class Booklist(ListView):
    model = Book
    template_name='books/books.html'

    def get_context_data(self, **kwargs):
        context = super(BookList, self).get_context_data(**kwargs)
        context['form'] = CreatePost.PostForm
        return context

    def post(self, request, *args, **kwargs):
        form  = CreatePost.PostForm(request.POST)
        if form.is_valid():
            form.save()
        return render(request, self.template_name, {'form': form })

class CreatePost(CreateView):
    template_name_suffix='_create'

    class PostForm(ModelForm):
        class Meta:
            model = Post
            fields = ['post']  
            widgets = {
            'post': forms.Textarea()
            }

class Posts(DetailView):
    model = Book
    template_name='books/post_create.html'
    slug_field = 'id'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['posts'] = Post.objects.all()
        return context

...

如何保存和显示与每本书相关的帖子数据?现在该程序显示了书单。在通过每个书籍项目(奇怪的设计)上的表格保存帖子并点击书籍项目后,它会显示帖子列表(所以在书籍项目的DetailView上)。

但无论点击哪个图书项目,都会显示所有帖子。并且,无论您保存帖子的哪个书项,帖子都只与第一本书相关联地保存。

我想保存帖子,并将其与特定图书相关联,该图书用于保存帖子的形式。我想(仅在书的DetailView上)显示与该书相关的帖子。

我认为我还需要提供表格传递书数据......但我尝试过的所有内容都没有用(添加模型=书籍等)。也许通过添加来自更新的形式Meta相同的代码(请参阅页面底部)?

更多代码:

models.py:

class Book(models.Model):
    book = models.CharField(max_length=1000, blank=False, null=False, default="1")

    def __str__(self):
        return self.book

class Post(models.Model):
    post = models.CharField(max_length=1000, blank=False, null=False)
    the_book = models.ForeignKey('Book', on_delete=models.CASCADE, default="1")
    date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.post

books.html:

<ul>
    {% for book in object_list %}
    <div class='ui card'>
    <a class="content" href='{% url 'books:posts' book.id %}'>
      <div class="header">{{ book }}</div>
    </a>

    <div class="ui bottom attached button">

       <form class='ui form' action='' method='post'> {% csrf_token %}
          {{ form.as_p }} 
          <div class='postbutton'>
          <input class='ui button' type="submit" value="Done" />
          </div>
      </form>

    </div>

    </div>
    {% empty %}
    <h5>You don't have any books!</h5>
    {% endfor %}
</ul>

post_create.html(名称将在稍后更改...):

 <ul>
    {% for post in posts %}
    <div class='ui card'>
    <a class="content">
      <div class="header">{{ post }}</div>
    </a>
    </div>
    {% empty %}
    <h5>You don't have any posts!</h5>
    {% endfor %}
</ul>

另外如何在DetailView上显示日期模型,post_create.html(以及Post模型中的其他数据)?

请原谅因新手而烦恼的事情......

再次,任何帮助将不胜感激。

更新

显示与每个特定图书项目相关联的帖子列表(在书籍的DetailView上):

将models.py更改为:

class Posts(DetailView):
    model = Book
    template_name='books/post_create.html'
    slug_field = 'id'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        books = Book.objects.get(pk=book)
        posts = Post.objects.filter(the_book=books)
        context['posts'] = posts
        return context

点击图书会显示,而不是发布列表,&#34; name&#39; book&#39;未定义&#34;。仅在(书)或(pk = book_id)或(pk = book.id)时相同。

之后:

class Posts(DetailView):
    model = Book
    template_name='books/post_create.html'
    slug_field = 'id'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        book = Book.objects.get(pk=book)
        posts = Post.objects.filter(the_book=book)
        context['posts'] = posts
        return context

它显示:&#34;本地变量&#39; book&#39;在转让前引用。&#34;

之后:

class Posts(DetailView):
    model = Book
    template_name='books/post_create.html'
    slug_field = 'id'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        book = Book.objects.get(pk=id)
        posts = Post.objects.filter(the_book=book)
        context['posts'] = posts
        return context

它显示:&#34; int()参数必须是字符串,类似字节的对象或数字,而不是&#39; builtin_function_or_method&#39;&#34;

我该怎么办?另请在帖子中间查看我的其他问题。抱歉有任何困惑。

2 个答案:

答案 0 :(得分:0)

您的应用会显示所有帖子,因为您使用的是Post.objects.all()。这将返回数据库中的所有Post个对象。相反,请使用您当前正在查看的图书来过滤它们。

我无法从您的代码中了解您如何获得正在查看的图书,但如果您拥有book ID,则可以执行以下操作:

book = Book.objects.get(pk=book_id)
posts = Post.objects.filter(the_book=book)

这样,posts将包含附加到图书的所有Post个对象。

您的所有帖子都被分配到第一本书的原因是因为您没有将图书传递到表单中的任何位置。因此,它默认为您在模型中定义的值:1

答案 1 :(得分:0)

哦,如果您使用DetailView,则可以使用self.object。它在DetailView中定义。

如果您查看DetailView代码(可以看到django github或docs on DataFrame.rolling),则可以找到get()get_object()

def get(self, request, *args, **kwargs):
    self.object = self.get_object()
    context = self.get_context_data(object=self.object)
    return self.render_to_response(context)

如您所见,当您通过DetailView进行请求时,使用self.object定义了self.get_object()

来自get_object()的{​​{1}}方法。(实际上,它来自DetailViewSingleObjectMixin继承了它。

DetailView

因此,您可以使用def get_object(self, queryset=None): """ Return the object the view is displaying. Require `self.queryset` and a `pk` or `slug` argument in the URLconf. Subclasses can override this to return any object. """ # Use a custom queryset if provided; this is required for subclasses # like DateDetailView if queryset is None: queryset = self.get_queryset() # Next, try looking up by primary key. pk = self.kwargs.get(self.pk_url_kwarg) slug = self.kwargs.get(self.slug_url_kwarg) if pk is not None: queryset = queryset.filter(pk=pk) # Next, try looking up by slug. if slug is not None and (pk is None or self.query_pk_and_slug): slug_field = self.get_slug_field() queryset = queryset.filter(**{slug_field: slug}) # If none of those are defined, it's an error. if pk is None and slug is None: raise AttributeError("Generic detail view %s must be called with " "either an object pk or a slug." % self.__class__.__name__) try: # Get the single item from the filtered queryset obj = queryset.get() except queryset.model.DoesNotExist: raise Http404(_("No %(verbose_name)s found matching the query") % {'verbose_name': queryset.model._meta.verbose_name}) return obj 。如下所示

self.object