首页 > 解决方案 > /product/7 'QuerySet' 对象的 AttributeError 没有属性 'category'

问题描述

所以AttributeError at /product/7 'QuerySet' object has no attribute 'category'每当我访问详细视图页面时都会出错。

它说没有属性category,但我已经与另一个名为categoryin 的模型建立了关系models.py,我尝试过使用category.id,但这也不起作用

views.py

def detailview(request, id):
    book = get_object_or_404(Book, pk=id)
    if request.user.is_authenticated:
        oof = CartItem.objects.filter(user=request.user).values_list('book', flat=True)
        lmao = OrderItem.objects.filter(user=request.user).values_list('book', flat=True)
        hehe = CartItem.objects.filter(user=request.user)
        number = 0
        for num in hehe:
            number += 1
        fianlprice = 0
        for item in hehe:
            fianlprice += item.book.price
        specific = Book.objects.filter(pk=id)
        matching_books = Book.objects.filter(category=specific.category).exclude(pk=id)[:3]
        reviews = Paginator(ProductReview.objects.filter(book=id), 5)
        review_page = request.GET.get('reviews')
        review_objects = reviews.get_page(review_page)
        one_two_star = ProductReview.objects.filter(book=id, rating=1).count() + ProductReview.objects.filter(book=id, rating=2).count()
        three_star = ProductReview.objects.filter(book=id, rating=3).count()
        four_star = ProductReview.objects.filter(book=id, rating=4).count()
        five_star = ProductReview.objects.filter(book=id, rating=5).count()
        checking = True
        if ProductReview.objects.filter(book=id, user=request.user).exists():
            checking = False
        if checking == False:
            gotten_review = ProductReview.objects.get(user=request.user)
        params = {'book':book, 'price':fianlprice, 'cart':oof, 'order':lmao, 'number':number, 'matching_books':matching_books, 'reviews':review_objects,
        'one_two_star':one_two_star, 'three_star':three_star, 'four_star':four_star, 'five_star':five_star, 'gotten_review':gotten_review, 'checking':checking}
        return render(request, 'main/detail.html', params)
    else:
        specific = Book.objects.filter(pk=id)
        matching_books = Book.objects.filter(category=specific.category).exclude(pk=id)[:3]
        reviews = Paginator(ProductReview.objects.filter(book=id), 5)
        review_page = request.GET.get('reviews')
        review_objects = reviews.get_page(review_page)
        one_two_star = ProductReview.objects.filter(book=id, rating=1).count() + ProductReview.objects.filter(book=id, rating=2).count()
        three_star = ProductReview.objects.filter(book=id, rating=3).count()
        four_star = ProductReview.objects.filter(book=id, rating=4).count()
        five_star = ProductReview.objects.filter(book=id, rating=5).count()
        params = {'book':book, 'matching_books':matching_books, 'reviews':review_objects, 'one_two_star':one_two_star, 'three_star':three_star, 'four_star':four_star, 'five_star':five_star}
        return render(request, 'main/detail.html', params)

detail.html

<h1>{{ book.name }}</h1>
<img src="/media/{{ book.image }}">
<h3>{{ book.description }}</h3>
<h2>{{ book.price }}</h2>

<main>
  <div class="container dark-grey-text mt-5">
    <!--Grid row-->
    <div class="row wow fadeIn">
      <!--Grid column-->
      <div class="col-md-6 mb-4">
        <img src="{{book.image.url}}" class="img-fluid" alt="">
      </div>
      <!--Grid column-->
      <!--Grid column-->
      <div class="col-md-6 mb-4">
        <!--Content-->
        <div class="p-4">
          <div class="mb-3">
            <a >
              <span class="badge purple mr-1" style="color:#3167EB">{{book.category.name}}</span>
            </a>
            <a href="">
            </a>
            <a href="">
            </a>
          </div>
          <p class="lead">
            <span class="mr-1">
            </span>
            <span>${{book.price}}</span>
          </p>
          <p class="lead font-weight-bold">{{book.name}}</p>
          <p>{{ book.description }}</p>
          {% if book.id in cart %}
          <form class="d-flex justify-content-left" method="POST" action="{% url 'removefromcartfordetail' %}">
            <!-- Default input -->
            <button class="btn btn-primary btn-md my-0 p" type="submit" name="removeid" value="{{book.id}}" style="background-color:#FF0000;">Remove from cart <i class="fa fa-shopping-cart ml-1"></i></button>
          </form>
          {% elif book.id in order %}
          <form class="d-flex justify-content-left" method="GET" action="{% url 'getorders' %}">
            <!-- Default input -->
            <button class="btn btn-primary btn-md my-0 p" type="submit" style="background-color:#FFFF00;">Item Owned <i class="fa fa-shopping-cart ml-1"></i></button>
          </form>
          {% else %}
          <form class="d-flex justify-content-left" method="POST" action="{% url 'addtocartfordetail' %}">
            <!-- Default input -->
            <button class="btn btn-primary btn-md my-0 p" type="submit" name="BookID" value="{{book.id}}" style="background-color:#3167EB;">Add to cart <i class="fa fa-shopping-cart ml-1"></i></button>
          </form>
          {% endif %}
        </div>
        <!--Content-->
      </div>
      <!--Grid column-->
    </div>
    <!--Grid row-->
    <hr>
    <!--Grid row-->
    <div class="row d-flex justify-content-center wow fadeIn">
      <!--Grid column-->
      <div class="col-md-6 text-center">
        <h2 class="my-4 h2">Related books to {{book.category.name}}</h2>
      </div>
      <!--Grid column-->
    </div>
    <!--Grid row-->
    <!--Grid row-->
    <div class="row wow fadeIn">
      <!--Grid column-->
      {% for matching_book in matching_books %}
      <div class="col-lg-4 col-md-12 mb-4 text-center" >
        <img src="{{ matching_book.image.url }}" class="img-fluid" alt="">
        <h2><a href="{% url 'detailview' matching_book.id %}">{{ matching_book.name }}</a> </h2>
      </div>
      {% endfor %}
      <!--Grid column-->
      <!--Grid column-->
      <!--Grid column-->
      <!--Grid column-->
      <!--Grid column-->
    </div>
    <!--Grid row-->
  </div>
</main>





{% if user.is_authenticated %}
    {% if checking == True %}
    <style> .rating {
        text-align: center;
        align-content: center;
    }

    /* :not(:checked) is a filter, so that browsers that don’t support :checked don’t 
      follow these rules. Every browser that supports :checked also supports :not(), so
      it doesn’t make the test unnecessarily selective */
    .rating:not(:checked) > input {
        position:absolute;
        top:-9999px;
        clip:rect(0,0,0,0);
    }
    .hehe2 {
      align-content: center;
      display: flex;
        justify-content: center;
    }

    .rating:not(:checked) > label {
        float:right;
        width:1em;
        /* padding:0 .1em; */
        overflow:hidden;
        white-space:nowrap;
        cursor:pointer;
        font-size:300%;
        /* line-height:1.2; */
        color:#ddd;
    }

    .rating:not(:checked) > label:before {
        content: '★ ';
    }

    .rating > input:checked ~ label {
        color: dodgerblue;
        
    }

    .rating:not(:checked) > label:hover,
    .rating:not(:checked) > label:hover ~ label {
        color: dodgerblue;
        
    }

    .rating > input:checked + label:hover,
    .rating > input:checked + label:hover ~ label,
    .rating > input:checked ~ label:hover,
    .rating > input:checked ~ label:hover ~ label,
    .rating > label:hover ~ input:checked ~ label {
        color: dodgerblue;
        
    }

    .rating > label:active {
        position:relative;
        top:2px;
        left:2px;
    }

    </style>
    <section >
        <div class="container justify-content-center hehe2" style="align-content: center;">
          <div class="row form-group ">
            <form method="POST">
              <div class="rating justify-content-center">
                <input type="radio" id="star5" name="rating" value="5"><label for="star5" title="Great">5 stars</label>
                <input type="radio" id="star4" name="rating" value="4"><label for="star4" title="Good">4 stars</label>
                <input type="radio" id="star3" name="rating" value="3"><label for="star3" title="Just fine">3 stars</label>
                <input type="radio" id="star2" name="rating" value="2"><label for="star2" title="Bad">2 stars</label>
                <input type="radio" id="star1" name="rating" value="1"><label for="star1" title="Very Bad">1 star</label>
              </div>
              <input type="text" name="name" class="form-control" id="exampleFormControlInput1" placeholder="Your name">
              <br>
              <input type="text" name="title" class="form-control" id="exampleFormControlInput1" placeholder="Title">
              <br>
              <textarea name="description" maxlength="500" class="form-control" id="exampleFormControlTextarea1" rows="3" placeholder="Description"></textarea>
              <br>
              <button type="submit" value="{{ book.id }}" name="BookID" class="btn btn-primary" style="background-color:#3167EB;">Post review</button>
            </form>
          </div>
        </div>
      </section>
    {% else %}
    <section >
        <div class="container  hehe2" style="align-content: center;">
          <h1> Your review: </h1>
          <br>
        </div>
        <div class="container hehe2">
          <h1>
            {% if gotten_review.rating == 1 %}
            <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
            {% elif gotten_review.rating == 2 %}
            <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
            {% elif gotten_review.rating == 3 %}
            <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
            {% elif gotten_review.rating == 4 %}
            <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
            {% elif gotten_review.rating == 5 %}
            <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
            <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
            {% endif %}
          </h1>
        </div>
        <div class="container hehe2">
          <h1> <strong>{{gotten_review.title}}</strong>
          </h1>
        </div>
        <div class="container hehe2 pb-5">
          <h3>{{gotten_review.description}} </h3>
        </div>
      </section>
    {% endif %}
{% else %}

{% endif %}

<div class="container text-center">
    <h1 style="color:#3167EB"> 5-Star reviews : {{five_star}} </h1>
    <h1 style="color:#00FF00"> 4-Star reviews : {{four_star}} </h1>
    <h1 style="color:#FFFF00"> 3-Star reviews : {{three_star}} </h1>
    <h1 style="color:#FF0000"> 1-2 Star reviews : {{one_two_star}} </h1>
    <h1 class="pt-5 pb-5"> Latest Reviews </h1>
</div>
{% if reviews %}
    {% if reviews.has_other_pages %}
    {% for review in reviews %}
    <div class="container">
        <h2> {{ review.name }} </h2>
        {% if review.rating == 1 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
        {% elif review.rating == 2 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
        {% elif review.rating == 3 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
        {% elif review.rating == 4 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
        {% elif review.rating == 5 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        {% endif %}
        <h3> {{ review.title }} </h3>
        <p> {{ review.description }} </p>
      </div>
    {% endfor %}
        {% if reviews.has_previous %}
        <li class="page-item">
            <a class="page-link" href="?reviews={{reviews.previous_page_number}}" aria-label="Previous" style="color:#3167EB;">
              <span aria-hidden="true">«</span>
              <span class="sr-only">Previous</span>
            </a>
          </li>
        {% else %}
        <li class="page-item">
            <a class="page-link disabled" aria-label="Previous" >
              <span aria-hidden="true">«</span>
              <span class="sr-only">Previous</span>
            </a>
          </li>
        {% endif %}
        {% for i in reviews.page_range %}
           {% if reviews.number == i %}
           <li class="page-item active"><a class="page-link">{{i}}</a></li>
           {% else %}
           <li class="page-item"><a class="page-link" href="?reviews={{i}}">{{i}}</a></li>
           {% endif %}
        {% endfor %}
        {% if reviews.has_next %}
        <li class="page-item">
            <a class="page-link" href="?reviews={{reviews.next_page_number}}" aria-label="Next" style="color:#3167EB;">
              <span aria-hidden="true">»</span>
              <span class="sr-only">Next</span>
            </a>
          </li>
        {% else %}
        <li class="page-item disabled">
            <a class="page-link" aria-label="Next">
              <span aria-hidden="true">»</span>
              <span class="sr-only">Next</span>
            </a>
          </li>
        {% endif %}
    {% else %}
    {% for review in reviews %}
    <div class="container">
        <h2> {{ review.name }} </h2>
        {% if review.rating == 1 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
        {% elif review.rating == 2 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#FF0000"></i>
        {% elif review.rating == 3 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#FFFF00"></i>
        {% elif review.rating == 4 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#00FF00"></i>
        {% elif review.rating == 5 %}
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        <i class="fa fa-star" aria-hidden="true" style="color:#3167EB"></i>
        {% endif %}
        <h3> {{ review.title }} </h3>
        <p> {{ review.description }} </p>
      </div>
    {% endfor %}
    {% endif %}
{% else %}
<h1>There are currently no reviews for this product!</h1>
{% endif %}

标签: pythondjango

解决方案


正如评论中所解释的,您正在执行一个返回查询集的过滤器,而不是模型的单个实例。

并且鉴于您的过滤器位于具有给定 ID 的主键上,您可以安全地get使用它,前提是您捕获了未找到的异常。这样,您将获得一个实例并能够.category使用它。

因此,您应该执行以下操作;

try:
    specific_book = Book.objects.get(pk=id)
    matching_books = Book.objects.filter(category=specific_book.category).exclude(pk=id)[:3]
except Book.DoesNotExist:
    # No book found
    raise

推荐阅读