我想按类别获取属性。
例如,当我尝试到达http://127.0.0.1:8000/category/Berlin时,会出现以下错误:
“ CategoryDetail”对象没有属性“ _state”
我在做什么错了?
我们将不胜感激任何帮助。
\U${1}.\L${2}
models.py
from django.db import models
from django.urls import reverse
# Create your models here.
class Property(models.Model):
title = models.CharField(max_length=140)
description = models.TextField()
rooms = models.PositiveIntegerField()
bed_rooms = models.PositiveIntegerField()
land_size = models.PositiveIntegerField()
slug = models.SlugField()
living_size = models.PositiveIntegerField()
build_year = models.PositiveIntegerField()
price = models.PositiveIntegerField()
category = models.ForeignKey(to='Category', null=True, related_name='categories', on_delete=models.SET_NULL,)
def get_absolute_url(self):
return reverse('properties:PropertyDetail', kwargs={'slug': self.slug})
def __str__(self):
return '{} - {}'.format(
self.title, self.build_year
)
class Category(models.Model):
name = models.CharField(max_length=150)
slug = models.SlugField()
def get_absolute_url(self):
return reverse('properties:CategoryDetail', kwargs={'slug': self.slug})
def __str__(self):
return '{}'.format(self.name)
views.py
from django.shortcuts import render
from .filters import PropertyFilter
# Create your views here.
from django.views.generic import (
TemplateView, DetailView, ListView
)
from .models import Property, Category
class HomePage(TemplateView):
template_name = 'home.html'
class PropertyList(ListView):
model = Property
class PropertyDetail(DetailView):
model = Property
class CategoryList(ListView):
model = Category
class CategoryDetail(ListView):
queryset = Category.categories
template_name = 'categorydetail.html'
def search(request):
property_list = Property.objects.all()
property_filter = PropertyFilter(request.GET, queryset=property_list)
return render(request, 'prop_list.html', {'filter': property_filter})
urls.py
项目网址
from django.urls import path
from .views import (PropertyList, PropertyDetail, HomePage, CategoryList, CategoryDetail)
app_name = 'properties'
urlpatterns = [
path('', HomePage.as_view(), name='home'),
path('categories', CategoryList.as_view(), name='categories'),
path('category/<slug:slug>', CategoryDetail.as_view(), name='CategoryDetail'),
path('properties', PropertyList.as_view(), name='PropertyList'),
path('property/<slug:slug>', PropertyDetail.as_view(), name='PropertyDetail'),
]
答案 0 :(得分:2)
请在类Property
中修改以下行:
category = models.ForeignKey(to='Category', null=True, related_name='categories', on_delete=models.SET_NULL,)
对此:
category = models.ForeignKey(
to='Category',
null=True,
related_name='properties',
on_delete=models.SET_NULL,
)
更改以粗体显示。进行更改的原因是,您想获取给定类别的 properties 。进行类似Category.categories
的查询会使读者感到困惑。
现在可以从related_name
对象访问properties
的{{1}}。在Category
类中的操作方式:
CategoryDetail
即使适用于:
queryset = Category.categories
无法工作。这是因为它将调用相关的描述符queryset = Category.properties
,在这里没有用。
您可以调用对象ReverseManyToOneDescriptor
的属性。一个例子是:
Category
第一部分Category.objects.get(pk=1).properties.all()
将返回单个对象Category.objects.get(pk=1)
,在第二部分Category
中,您将对象properties.all()
称为管理者properties
。使用方法Category
,您将检索一个包含给定all()
对象的所有properties
的QuerySet。
请记住,使用类似Category
的方法将不起作用。 Category.objects.all().properties.all()
将返回不具有属性Category.objects.all()
的QuerySet。
考虑到这一点,最佳方法将是@Alasdair建议使用properties
。您想列出所有属性以获取类别,这会使您感到困惑。但是,您仍在显示类别的详细信息。在DetailView
中使用DetailView
是一种更干净,更好的方法。
非常简单:
Category
将完成这项工作。默认模板名称为class CategoryDetail(DetailView):
model = Category
,您无需显式指定它。只是要与其他类保持一致。
详细信息视图的内部逻辑将检索单个对象category_detail.html
,在模板中,您可以访问该对象的Category
:
properties
您可以使用{% for property in object.properties.all %}
{{ property }}
{% endfor %}
代替object.properties.all
,它更加冗长,并提高了可读性。
您要更改此设置,例如:
category.properties.all
我希望这可以使您前进。
答案 1 :(得分:1)
首先,按照@cezar的建议将related_name
更改为properties
,因为它用于获取类别的相关 properties 。
category = models.ForeignKey(to='Category', null=True, related_name='categories', on_delete=models.SET_NULL,)
我建议您使用DetailView
作为类别,
class CategoryDetail(DetailView):
model = Category
template_name = 'categorydetail.html'
然后,您可以使用反向关系来访问模板中的属性:
{% for property in category.properties.all %}
如果您确实要为CategoryDetail
使用列表视图,则需要覆盖get_queryset
并使用slug
。例如,您可以这样做:
from django.shortcuts import get_object_or_404
class PropertiesForCategory(ListView):
template_name = 'categorydetail.html'
def get_queryset(self):
category = get_object_or_404(Category, slug=self.kwargs['slug']
return category.properties.all()
然后在模板中,您将使用以下命令循环查询集:
{% for property in object_list %}