简体   繁体   English

在django中编写两个相似的ListView或渲染到不同模板中的相似列表的最佳方法是什么?

[英]What is the best way to write two similiar ListView or render to similar lists in different templates in django?

I want to show a user the whole list of cats on one page and the list of cats that belongs to that user on another page. 我想在一个页面上向用户显示猫的整个列表,在另一页面上显示属于该用户的猫的列表。 These two lists are almost identical except for one of them is filtered by self.request.user . 这两个列表几乎相同,除了其中一个列表是由self.request.user过滤的。 Firstly, I wrote two different ListView but their querysets are practically the same. 首先,我编写了两个不同的ListView,但是它们的查询集实际上是相同的。 I don't know how to inherit one class based view from another. 我不知道如何从另一个继承一个基于类的视图。 Is it possible? 可能吗?

According to my lack of knowledge of inheritance of the CBV, I put these lines into get_context_data : 根据我对CBV继承的了解,我将这些行放入get_context_data

cats_in_agent_base = Cat.objects.filter(cat_owner__exact=user)
context['cats_in_user_base'] = cats_in_user_base

On a personal owner page django will refer only to 'cats_in_user_base' but not to cat_list . 在个人所有者页面上,django将仅引用'cats_in_user_base' ,而不cat_list But, of course, a user can't filter the list by get requests and paginate it right now. 但是,当然,用户不能立即通过获取请求过滤列表并对其进行分页。

What is a good way to solved the problem? 什么是解决问题的好方法? How to inherit the queryset from one View to another? 如何继承queryset从一个View到另一个? For example, what if I want to show on a DetailView page of the cat the list of similar cats by price or color? 例如,如果我想在猫的DetailView页面上显示按价格或颜色列出的相似猫的列表,该怎么办? I'd like to use the same queryset from CatListView and filter it into get_context_data method. 我想从CatListView使用相同的CatListView并将其过滤到get_context_data方法中。

My CatListView: 我的CatListView:

class CatListView(LoginRequiredMixin, ListView):
    template_name = 'ha/cat_list_template.html'
    context_object_name = 'cat_list'

    def get_queryset(self):
        max_price = self.request.GET.get('max_price')
        if max_price is None or max_price == '':
            max_price = 1000000000
        min_price = self.request.GET.get('min_price')
        if min_price is None or min_price == '':
            min_price = min(Cat.objects.filter().values_list('cat_price'))[0]

        cat_list = Cat.objects.filter(cat_price__gte=min_price) \
            .filter(cat_price__lte=max_price).order_by('-cat_pub_date')

        paginator = Paginator(cat_list, 20)
        page = self.request.GET.get('page')
        try:
            cat_list = paginator.page(page)
        except PageNotAnInteger:
            cat_list = paginator.page(1)
        except EmptyPage:
            cat_list = paginator.page(paginator.num_pages)

        return cat_list

    def get_context_data(self, **kwargs):
        user = self.request.user
        context = super(CatListView, self).get_context_data(**kwargs)
        cats_in_agent_base = Cat.objects.filter(cat_owner__exact=user)
        context['cats_in_user_base'] = cats_in_user_base
        return context 

I think you can do this in some ways, I will try to give some basic ways to implement this. 我认为您可以通过某些方式做到这一点,我将尝试给出一些基本的实现方式。

I can see in your get_context_data method that you're filtering by user always and sending two list of cats to the template, I don't think that's a good idea. 我可以在您的get_context_data方法中看到您一直在按用户过滤并将两个猫列表发送到模板,我认为这不是一个好主意。

You could do this: 您可以这样做:

Add a GET param to your url: GET参数添加到您的网址中:

http://yourdomain/your-path-to-cat-list/?owned_by_user=1
# 1 it's not a pk is to say True
# Let's use 1 and 0 for this example
# You could use any other value as a flag

# Then you get that querystring in your get_queryset method

def get_queryset(self):
    max_price = self.request.GET.get('max_price')
    if max_price is None or max_price == '':
        max_price = 1000000000
    min_price = self.request.GET.get('min_price')
    if min_price is None or min_price == '':
        min_price = min(Cat.objects.filter().values_list('cat_price'))[0]

    cat_list = Cat.objects.filter(cat_price__gte=min_price) \
        .filter(cat_price__lte=max_price).order_by('-cat_pub_date')
    if int(self.request.GET.get('owned_by_user')):
        cat_list = cat_list.filter(cat_owner__exact=self.request.user)

    paginator = Paginator(cat_list, 20)
    page = self.request.GET.get('page')
    try:
        cat_list = paginator.page(page)
    except PageNotAnInteger:
        cat_list = paginator.page(1)
    except EmptyPage:
        cat_list = paginator.page(paginator.num_pages)

    return cat_list

If you want to do a new view for this, but don't repeat the same code, you can extend from your own view: 如果您想为此做一个新视图,但不重复相同的代码,则可以从您自己的视图扩展:

# You have
class CatListView(LoginRequiredMixin, ListView):
    # You could use this view for the complete list
    ...

# You can create a new one
# And modify get_queryset method

class OwnedByUserCatListView(CatListView):
    def get_queryset(self):
        max_price = self.request.GET.get('max_price')
        if max_price is None or max_price == '':
            max_price = 1000000000
        min_price = self.request.GET.get('min_price')
        if min_price is None or min_price == '':
            min_price = min(Cat.objects.filter().values_list('cat_price'))[0]

        cat_list = Cat.objects.filter(cat_price__gte=min_price) \
            .filter(cat_price__lte=max_price).filter(cat_owner__exact=self.request.user).order_by('-cat_pub_date')

        paginator = Paginator(cat_list, 20)
        page = self.request.GET.get('page')
        try:
            cat_list = paginator.page(page)
        except PageNotAnInteger:
            cat_list = paginator.page(1)
        except EmptyPage:
            cat_list = paginator.page(paginator.num_pages)

        return cat_list

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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