我是django的新手。我正在尝试仅使用models.Manager
个实例与published=True
显示。在终端中没有错误。我做错了什么?我觉得这与我的观点有关。
任何帮助将不胜感激。
models.py
from django.db import models
# Create your models here.
class BlogPostManager(models.Manager):
use_for_related_fields = True
def freetosee(self, **kwargs):
return self.filter(published=True, **kwargs)
class Post(models.Model):
NOT_RATED = 0
RATED_G = 1
RATED_PG = 2
RATED_R = 3
RATINGS =(
(NOT_RATED, 'NR-Not Rated'),
(RATED_G, 'G - General Audience'),
(RATED_PG, 'Parental'),
(RATED_R, 'Restriced'),
)
title = models.CharField(max_length=140)
body = models.TextField()
published = models.BooleanField(default=False)
rating = models.IntegerField(
choices=RATINGS,
default=NOT_RATED,
)
objects = BlogPostManager()
def __str__(self):
return self.title
views.py
from django.shortcuts import render
# Create your views here.
from django.views.generic import DetailView, ListView
from .models import Post
class PostListView(ListView):
model = Post
context_object_name = 'posts'
template_name = 'postlist.html'
模板
{% extends "base.html" %}
{% block content %}
{% for post in posts.objects.freetosee %}
{{ post.title }} - {{ post.body }}
{% endfor %}
{% endblock %}
urls.py
from django.urls import path, include
from django.views.generic import TemplateView
from .views import PostListView
app_name = 'blog'
urlpatterns = [
path('', TemplateView.as_view(template_name='home.html'), name='home'),
path('list/', PostListView.as_view(), name='post-list'),
]
我希望看到ListView
中published=True
的所有模型实例
答案 0 :(得分:1)
这不是它的工作方式。 posts
是一个查询集,没有objects
属性。您需要在视图中调用它:
class PostListView(ListView):
queryset = Post.objects.freetosee()
context_object_name = 'posts'
template_name = 'postlist.html'
然后在模板中执行{% for post in posts %}
答案 1 :(得分:1)
由于您使用的是2.1
根据{{3}} use_for_related_fields = True
被删除
您必须在模型base_manager_name
中使用Meta
。像这样:
class Post(models.Model):
# your fields here
objects = BlogPostManager()
class Meta:
base_manager_name = 'objects'
如上面注释中所建议的,当您设置了context_object_name
时,您不必做posts.objects.freetouse
将模板更改为:
{% extends "base.html" %}
{% block content %}
{% for post in posts %}
{{ post.title }} - {{ post.body }}
{% endfor %}
{% endblock %}
来自django 2.0 deprecation docs的:ListView
有一个get_queryset()
方法,我们可以重写。以前,它只是返回queryset
属性的值,但是现在我们可以添加更多逻辑。
这意味着您可以
class PostListView(ListView):
queryset = Post.objects.freetosee()
context_object_name = 'posts'
template_name = 'postlist.html'
,您也可以这样做:
class PostListView(ListView):
context_object_name = 'posts'
template_name = 'postlist.html'
def get_queryset(self):
# this method can be used to apply as many filters as you want
# Just a quick example,
# filter_id = self.request.GET.get('filter_by')
# if filter_id:
# return Post.objects.filter(id=filter_id)
return Post.objects.freetosee()
注意::请理解Views
在那里可以处理所有数据,并将其传递给templates
。您进行managers
来将自定义查询方法放在一个位置。因此,它是一种事物的场所,除非非常必要,否则您的模板不应发出任何查询请求。 templates
仅用于显示。如果要在filters
中使用templates
,请使用模板标记。这样可以使您的代码干净且可读。