python - Django - DetailView - `get_object` 函数混淆

标签 python django django-class-based-views detailview

我是 CBV 新手。不知道为什么这不起作用...

View .py

class ItemDetailView(DetailView):
    '''display an individual item'''
    model = Item
    template_name = 'boutique/item.html'
    context_object_name = 'item'

    # With model specified, following code would be redundant, wouldn't it?? However...
    # def get_object(self):
        # return get_object_or_404(Item, pk=self.kwargs.get('item_pk'))

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # add categories for navbar link texts
        context['categories'] = Category.objects.all()

        print('\ncontext= ', context, '\n')
        return context

/item_8/处的 AttributeError 通用详细信息 View ItemDetailView 必须使用 URLconf 中的对象 pk 或 slug 进行调用。

并且上下文没有被打印出来。

<小时/>

如果我将 get_object 添加到代码中,它就可以正常工作:


class ItemDetailView(DetailView):
    '''display an individual item'''
    # model = Item
    template_name = 'boutique/item.html'
    # context_object_name = 'item'

    def get_object(self):
        return get_object_or_404(Item, pk=self.kwargs.get('item_pk'))

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # add categories for navbar link texts
        context['categories'] = Category.objects.all()

        print('\ncontext= ', context, '\n')
        return context
<小时/>

但是,如果我将 get_object 函数更改为:

    def get_object(self):
        obj = super().get_object()
        obj = get_object_or_404(Item, pk=self.kwargs.get('item_pk'))
        # obj = obj.filter(pk=self.kwargs.get('item_pk')) # doesn't work, same error
        # obj = obj.get(pk=self.kwargs.get('item_pk')) # doesn't work, same error

        return obj

ImproperlyConfigured at/item_8/ItemDetailView 缺少查询集。定义 ItemDetailView.model、ItemDetailView.queryset,或重写 ItemDetailView.get_queryset()。

我很困惑... DetailView 应该可以工作而无需定义 get_object 不?

<小时/>

其他文件:

url.py

app_name = 'boutique'
urlpatterns = [
    # show index page
    path('', views.IndexView.as_view(), name='index'),

    # show a specific item
    path('item_<int:item_pk>/', views.ItemDetailView.as_view(), name='item'),

    # show categories of products for men or women
    path('<slug:gender>/', views.CategoryListView.as_view(), name='show-all'),

    # show a specific category for men or women
    path('<slug:gender>/cat_<int:category_pk>/', views.CategoryListView.as_view(), name='category'),

    # show a specific subcategory under a specific category for men or women
    path('<slug:gender>/cat_<int:category_pk>/subcat_<int:subcategory_pk>/', views.CategoryListView.as_view(), name='subcategory'),

]

模型.py

class Item(models.Model):
    '''Each item represents a product'''
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    subcategory = models.ForeignKey(
        SubCategory, on_delete=models.CASCADE, null=True, blank=True)
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    price = models.IntegerField(default='0')
    discount = models.IntegerField(null=True, blank=True)
    uploaded_date = models.DateTimeField(
        auto_now_add=True, null=True, blank=True)

    class Meta:
        ordering = ['-uploaded_date']

    def __str__(self):
        return self.name

    def discounted_price(self):
        '''to calculate the price after discount'''
        return int(self.price * (100 - self.discount) * 0.01)

    def get_item_url(self):
        return reverse('boutique:item', kwargs={'item_pk': self.pk})

项目.html

<!-- display each item in its own box -->
<div class="col-6 col-md-4 col-lg-3 px-1 px-sm-2 d-flex flex-column">

    <!-- image anchor -->
    <a href="{{ item.get_item_url }}">
        <img class="rounded-sm" src="{{item.itemimage_set.first.image.url}}" width="100%"
    alt=""></a>
    <!-- /image anchor -->

    <!-- item price tag -->
    <div class="text-left p-1 mt-auto" style="font-size: 16px;">
        <div class="font-weight-light pt-2">
            <a href="{{ item.get_item_url }}" class="text-dark mb-1">{{item}}</a>
        </div>

        <div class="font-weight-lighter">
            {% if item.discount %}

            <p>
                <strike class="text-muted">&#8381;&nbsp;{{item.price}}</strike>
                <b class="text-danger">&#8381;&nbsp;{{item.discounted_price}}</b>
                <small class="text-danger">(-{{item.discount}}%)</small>
            </p>

            {% else %}
            <p>&#8381;&nbsp;{{item.price}}</p>

            {% endif %}
        </div>
    </div>
    <!-- /item price tag -->

</div>

最佳答案

您的第一个示例是正确的,您不需要显式定义 get_object() 但您应该使用 pk 参数而不是 item_pk使用详细信息 CBV 时的 url 路径:

path('item_<int:pk>/', views.ItemDetailView.as_view(), name='item'),

因为默认情况下 get_object() 方法使用 self.kwargs["pk"] 来搜索对象。

如果您仍然想使用item_pk,您需要在 View 中使用pk_url_kwarg指定:

class ItemDetailView(DetailView):
    pk_url_kwarg = 'item_pk'

来自docs :

The URLconf here uses the named group pk - this name is the default name that DetailView uses to find the value of the primary key used to filter the queryset.

If you want to call the group something else, you can set pk_url_kwarg on the view. More details can be found in the reference for DetailView

关于python - Django - DetailView - `get_object` 函数混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60113746/

相关文章:

Python正则表达式删除括号中的注释或数字

python - 如何在 Wavenet 的 Keras 实现中准备输入以进行时间序列预测

django - 如何在Django中基于类的 View 中覆盖 `as_view`?

python - 我可以在 ASE 上移植现有的 Python 应用程序吗?

python - 将值替换为总行中的百分比

python - Django 表单不运行 form.is_valid

python - 尝试创建寄存器 View 时出现 NOT NULL 约束失败错误

python - 如何获取模板中任意给定级别的深度级别

python - 如何对过滤后的搜索查询进行排序/排序并将其呈现在 Django 上的另一个模板上?

Django相关模型和UpdateView字段