'CategoryDe​​tail'对象没有属性'_state'

时间:2019-01-11 13:59:45

标签: django django-templates django-views

我想按类别获取属性。

例如,当我尝试到达http://127.0.0.1:8000/category/Berlin时,会出现以下错误:

  

“ CategoryDe​​tail”对象没有属性“ _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'),
]

2 个答案:

答案 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 %}