简体   繁体   中英

How to pass 2 arguments to def get_queryset?

Good evening, I have a problem while learning Django. The point is that I am doing a training news site, and there is such an item as "public" - whether the news is published or not. And to display only published news, use "def get_queryset" But I need to display news only with public = True and by the date the news was created

views.py

class news(ListView):
model = Post
template_name = 'flatpages/new.html'
context_object_name = 'news'
# paginate_by = 6

ordering = '-data'

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['cate'] = Category.objects.all()
    return context

def get_queryset(self):
    return Post.objects.filter(public=True)

models.py

class Category(models.Model):
category_name = models.CharField(max_length=64, unique=True)
subscribers = models.ManyToManyField(User, blank=True, null=True)


class Meta:
    verbose_name = 'Категория'
    verbose_name_plural = 'Категории'

def __str__(self):
    return self.category_name

class Post(models.Model):
PostAuthor = models.ForeignKey(Author, on_delete=models.CASCADE, verbose_name='Автор поста')

PostNews = 'PN'
PostArticle = 'PA'

# «статья» или «новость»
POSITIONS = [
    (PostArticle, 'Статья'),
    (PostNews, 'Новость'),
]

postCategory = models.ManyToManyField(Category, verbose_name='Категория поста',  through='PostCategory')
title = models.CharField(max_length=50, verbose_name='Название')
positions = models.CharField(max_length=2, choices=POSITIONS, default=PostArticle, verbose_name='Тип поста')
category_id = models.ForeignKey(Category, verbose_name='Категория', null=True, on_delete=models.CASCADE, related_name='category_id')
data = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
data_update = models.DateTimeField(auto_now=True, verbose_name='Дата редактирования')
photo = models.ImageField(upload_to='photos/%Y/%m/%d/', verbose_name='Фото', blank=True, default='/photos/def/1.jpg/')
previewName = models.CharField(max_length=128, verbose_name='Превью поста')
text = models.TextField(verbose_name='Текст поста')
rating = models.SmallIntegerField(default=0, verbose_name='Рейтинг')
public = models.BooleanField(default=True, verbose_name='Опубликовано')

def like(self):
    self.rating +=1
    self.save()

def dislike(self):
    self.rating -=1
    self.save()

def preview(self):
    return self.text[0:124] + '...'

def __str__(self):
    return self.title

class Meta:
    verbose_name = 'Пост'
    verbose_name_plural = 'Посты'

def get_absolute_url(self):
    return f'/news/{self.pk}'

html page

        <div class="col-md-8">
        {%for el in news%}
        <div class="card mb-3">
            <div class="card-header">
                Категории: {{el.category_id}}
            </div>
            <br>
            <div class="row g-0">
                <div class="col-md-4">
                    {%if el.photo%}
                    <img src="{{el.photo.url}}" alt="" width="275" class="mr-3">
                    {%endif%}
                </div>
                <div class="col-md-8">
                    <div class="card-body">
                        <h5 class="card-title"><a style="color: #000000;" href="{% url 'news_detail' el.id %}">{{ el.title|censor_filter }}</a></h5>
                        <p class="card-text">{{ el.text|censor_filter|truncatewords:150 }}</p> <a
                            href="{% url 'news_detail' el.id %}" class="btn btn-primary">Читать полную новость</a>
                    </div>
                </div>
                <br>
                <div
                        class="card-footer text-muted " style="text-align: right;">Рейтинг статьи: {{el.rating}}<br>
                    Дата публикации {{ el.data|date:'d M Y H:m' }}
                </div>
            </div>
        </div>
        {%endfor%}
    </div>

https://i.stack.imgur.com/BG56m.png

If you override the get_queryset , Django will no longer order the queryset, since that is implemented in the basic implementation of the view. You should order in the .get_queryset method with:

class news(ListView):
    model = Post
    template_name = 'flatpages/new.html'
    context_object_name = 'news'
    # paginate_by = 6

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['cate'] = Category.objects.all()
        return context
    
    def get_queryset(self):
        #                          use order_by(…) ↓
        return Post.objects.filter(public=True)

Note : In Django, class-based views (CBV) often have a …View suffix, to avoid a clash with the model names. Therefore you might consider renaming the view class to NewsView , instead of news .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM