反向外键重复迭代

时间:2017-06-29 05:04:21

标签: django django-models

我正在尝试使用Django的教程来制作带有书籍的本地图书馆网站。 其中一个挑战是制作作者详细视图,其中列出了作者编写的所有书籍。我无法为作者显示任何书籍信息。

Model.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django.urls import reverse
import uuid

# Create your models here.

class Genre(models.Model):
    """
        Model resprenting the book genre
    """
    name=models.CharField(max_length=200, help_text="Enter a book genre")
    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    summary = models.TextField(max_length=1000, help_text="Enter a brief description")
    isbn = models.CharField('ISBN', max_length=13, help_text="13 character ISBN field")
    genre = models.ManyToManyField(Genre, help_text="Select a genre for this book")

    def __str__(self):
        return self.title
    def get_absolute_url(self):
        return reverse('book-detail', args=[str(self.id)])

    def display_genre(self):
        return ', '.join([genre.name for genre in self.genre.all()[:3] ])

    display_genre.short_description = 'Genre'


class BookInstance(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text="Unique book number")
    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
    imprint = models.CharField(max_length=200)
    due_back = models.DateField(null=True, blank=True)

    LOAN_STATUS = (
            ('d', 'Maintenance'),
            ('o', 'On loan'),
            ('a', 'Available'),
            ('r', 'Reserved'),
        )

    status = models.CharField(max_length=1, choices=LOAN_STATUS, blank=True, default='d', help_text="Book Availability")

    class Meta:
        ordering = ['due_back']

    def __str__(self):
        return ('%s (%s)' %(self.id, self.book.title))

class Author(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    date_of_birth = models.CharField(max_length=10, null=True, blank=True)
    date_of_death = models.CharField(max_length=10, null=True, blank=True)

    def get_absolute_url(self):
        return reverse('author-detail', args=[str(self.id)])
    def __str__(self):
        return ('%s, %s' % (self.last_name, self.first_name))

    def display_books(self):
        books = Book.objects.get(pk=self.id)
        return books.book_set.all()

    display_books.short_description = 'Books'

author_detail.html

真的输了!

{% extends "base.html" %}

{% block content %}
<h1>Author: {{ author }}</h1>
  <p><strong>Date of Birth:</strong> {{ author.date_of_birth }}</p>  
  <p><strong>Date of Death:</strong> {{ author.date_of_death }}</p>  
  <!--<p><strong>Books:</strong> {% for books in book.author.pk.all %} {{ book.author }}{% if not forloop.last %}, {% endif %}{% endfor %}</p>  -->


  <div style="margin-left:20px;margin-top:20px">
   <h4>Books</h4>
   {% for books in book.all %}
   <p>{{ books }} Testing Vars {{ book.author_set }} Get copies from key {{ book.author.pk }} </p>
   {% endfor %}
  </div>
  {% endblock %}

Views.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render
from django.views import generic

# Create your views here.

from .models import Book, Author, BookInstance, Genre

def index(request):
    num_books=Book.objects.all().count()
    num_instances=BookInstance.objects.all().count()
    #available books
    num_instances_available=BookInstance.objects.filter(status__exact='a').count()
    num_authors=Author.objects.count()

    return render(request, 
        'index.html', 
        context={'num_books': num_books, 'num_instances': num_instances, 
            'num_instances_available' : num_instances_available, 'num_authors': num_authors},
    )

class BookListView(generic.ListView):
   model = Book

class BookDetailView(generic.DetailView):
    model = Book


class AuthorListView(generic.ListView):
    model = Author

class AuthorDetailView(generic.DetailView):
    model = Author

1 个答案:

答案 0 :(得分:0)

假设在author_detail.html ListView中使用AuthorDetailView,我建议您对模板进行一些更改,可能是这样的,

{% block content %}
<h1>Author: {{ object.first_name }} {{ object.last_name }}</h1>
  <p><strong>Date of Birth:</strong> {{ object.date_of_birth }}</p>  
  <p><strong>Date of Death:</strong> {{ object.date_of_death }}</p>  

  <div style="margin-left:20px;margin-top:20px">
   <h4>Books</h4>
   {% for book in object.book_set.all %}
   <p>{{ book.title }}</p>
   {% endfor %}
  </div>
  {% endblock %}

由于您没有覆盖ListView的get_context_data()方法,因此默认的context_variable_name将为object。您可能需要通过Author引用object实例。

相关问题