我是 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">₽ {{item.price}}</strike>
<b class="text-danger">₽ {{item.discounted_price}}</b>
<small class="text-danger">(-{{item.discount}}%)</small>
</p>
{% else %}
<p>₽ {{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/