<django.db.models.query_utils.DeferredAttribute object at ... > вместо значения данных в базе данных PostgreSQL

Я пытаюсь отобразить значение на html-странице, но значение просто возвращается как <django.db.models.query_utils.DeferredAttribute object at ... >. Проблема заключается в переменной 'card_name'.

Вот мои файлы кода из моего проекта Django:

Models.py:

class mProSet1990(models.Model):
    Image = models.CharField(max_length=255, primary_key=True)
    Card = models.CharField(max_length=255)

    class Meta:
        managed = False
        db_table = '1990 Pro Set'

Views.py:

def ProSet1990_1(request):
    # Fetch the card details from the database
    card_1 = mProSet1990.objects.get(Card="David Seaman #1")

    # Use the web scraping bot to get the lowest card price
    lowest_price = get_lowest_card_price(f'{mProSet1990.Set} {mProSet1990.Card}')

    # Pass the data to the template
    context = {
        'card_1': card_1,
        'card_name': mProSet1990.Card,
        'lowest_price': lowest_price,
    }

    # Render the template with the data
    return render(request, 'Application/ProSet1990_1.html', context)

ProSet1990_1.html body:

<body>
    <h1>{{ card_name }}</h1>
    {% if lowest_price %}
        <p>Lowest Price: {{ lowest_price }}</p>
    {% else %}
        <p>Price not available</p>
    {% endif %}
</body>

mProSet1990.Set и mProSet1990.Card не извлекают фактические значения, они возвращаются как объект <django.db.models.query_utils.DeferredAttribute по адресу ... >.

В вашем коде есть несколько ошибок. Вы передаете атрибуты неустановленного класса mProSet1990, а не значения возвращаемого запроса card_1. Это проблема как для lowest_price, так и для context. Это просто исправить (измените контекст на "card_name": card_1.Card). Однако вместо этого я бы рекомендовал использовать следующее:

models.py

class mProSet1990(models.Model):
    Image = models.CharField(max_length=255, primary_key=True)
    Card = models.CharField(max_length=255)

    class Meta:
        managed = False
        db_table = '1990 Pro Set'

    def get_lowest_price(self):
        # BUG: This model does not define `Set`!
        return get_lowest_card_price(f'{self.Set} {self.Card}')

views.py

def ProSet1990_1(request):
    card = mProSet1990.objects.get(Card="David Seaman #1")
    lowest_price = get_lowest_card_price(f'{card.Set} {card.Card}')

    context = {
        'card': mProSet1990.objects.get(Card="David Seaman #1"),
    }

    return render(request, 'Application/ProSet1990_1.html', context)

ProSet1990_1.html

<body>
    <h1>{{ card.Card }}</h1>
    {% with card.get_lowest_price as lowest_price %}
        {% if lowest_price %}
            <p>Lowest Price: {{ lowest_price }}</p>
        {% else %}
            <p>Price not available</p>
        {% endif %}
    {% endwith %}
</body>

При этом я бы пошел гораздо дальше. В Django довольно много батарей, и вы делаете лишнюю работу, чтобы воссоздать то, что уже делает DetailView. Кроме того, у вас не очень хорошая модель данных. Я бы начал с чего-то вроде следующего.

app_name/models.py

from decimal import Decimal

import requests
from django.db import models


class Collection(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, unique=True)

    def __str__(self):
        return self.name

    def update_cards(self):
        cursor = None
        while True:
            response = requests.get(
                f"https://www.sportscardspro.com/console/{self.slug}",
                params={"cursor": cursor, "format": "json"},
                timeout=5,
            )
            response.raise_for_status()
            data = response.json()

            for product in data["products"]:
                parsed = Card.parse_api_data(product)
                Card.objects.update_or_create(slug=parsed["slug"], defaults=parsed)

            cursor = data.get("cursor")
            if not cursor:
                break


class Card(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, unique=True)
    image = models.ImageField(null=True, blank=True)
    ungraded_price = models.DecimalField(max_digits=10, decimal_places=2)
    grade_9_price = models.DecimalField(max_digits=10, decimal_places=2)
    grade_10_price = models.DecimalField(max_digits=10, decimal_places=2)

    collection = models.ForeignKey(Collection)

    def __str__(self):
        return self.name

    @classmethod
    def parse_api_data(cls, data):
        return {
            "name": data["productName"],
            "slug": data["productUri"],
            "image": cls.download_image(data["imageUri"]),
            "ungraded_price": cls.parse_price(data["price1"]),
            "grade_9_price": cls.parse_price(data["price3"]),
            "grade_10_price": cls.parse_price(data["price2"]),
        }

    @classmethod
    def parse_price(cls, price):
        return Decimal(price.replace("$", "").replace(",", ""))

    @classmethod
    def download_image(cls, url):
        # Code to download the image and populate self.image.
        # Example: https://stackoverflow.com/questions/16174022/download-a-remote-image-and-save-it-to-a-django-model
        return None

app_name/views.py

from django.views.generic.detail import DetailView

from .models import Card


class CardDetailView(DetailView):
    model = Card

app_name/urls.py

from django.urls import path

from .views import CardDetailView

urlpatterns = [
    path("<slug:slug>/", CardDetailView.as_view(), name="card-detail"),
]

app_name/templates/app_name/card_detail.html

<body>
  <h1>{{ object }}</h1>
  <p>Ungraded: ${{ object.ungraded_price }}</p>
  <p>Grade 9: ${{ object.ungraded_price }}</p>
  <p>PSA 10: ${{ object.ungraded_price }}</p>
</body>
Вернуться на верх