首页 > 解决方案 > Django:如何使用 filter() 或不基于可选参数?

问题描述

正如您在此 url 中看到的,city参数是可选的:

re_path(r'all/(?P<category>\w+)/(?P<page_num>\w+)/?/(?P<city>\d+)?', views.show_all_objects, name="show-all-objects")

视图.py:

def show_all_objects(request, category, page_num, city=''):
    if category == 'restaurants':
        objects = Item.objects.instance_of(Restaurant)
    elif category == 'sportfitness':
        objects = Item.objects.instance_of(SportFitness)
    elif category == 'carservice':
        objects = Item.objects.instance_of(CarService)
    elif category == 'beautysalon':
        objects = Item.objects.instance_of(BeautySalon)
    elif category == 'fastfood':
        objects = Item.objects.instance_of(FastFood)
    elif category == 'carwash':
        objects = Item.objects.instance_of(CarWash)
    elif category == 'fun':
        objects = Item.objects.instance_of(Fun)
    elif category == 'other':
        objects = Item.objects.instance_of(Other)

    paginator = Paginator(objects, 2)
    objects = paginator.get_page(page_num)

    context = {
        'objects': objects,
        'category': category,
        'page_num': page_num,
    }

    return render(request, 'show_all_objects.html', context)

我想如果 city 参数设置为 add .filter(city=city),我可以这样做,if/else但它不遵循 DRY 原则。

标签: pythondjangodjango-2.2

解决方案


尝试使用字典来映射 instance_of 方法的参数。

def show_all_objects(request, category, page_num, city=''):

    params_map = {
        'restaurants': Restaurant,
        'sportfitness': SportFitness,
        'carservice': CarService,
        'beautysalon': BeautySalon,
        'fastfood': FastFood,
        'carwash': CarWash,
        'fun': Fun,
        'other': Other,
    }

    objects = Item.objects.instance_of(params_map.get(category))

    # If city is provided
    if city:
        objects = objects.filter(city=city)    

    paginator = Paginator(objects, 2)
    objects = paginator.get_page(page_num)

    context = {
        'objects': objects,
        'category': category,
        'page_num': page_num,
    }

    return render(request, 'show_all_objects.html', context)

推荐阅读