Change query parameter via select

半城伤御伤魂 提交于 2019-12-13 06:01:59

问题


I have a model Dish and a model Menu:

class MenuItem(models.Model):
    dish_name=models.TextField(unique=False)
    price=models.DecimalField(max_digits=5,decimal_places=2,blank=True)
    main_ngredient=models.TextField(unique=False)
    course=models.CharField(max_length=100)
    menu=models.ForeignKey('Menu')
    def __unicode__(self):
        return name
class Menu(models.Model):
    restaurant=models.TextField(unique=False)
    year=models.IntegerField(unique=False)
    location=models.TextField(unique=False)
    status=models.CharField(unique=False,max_length=20)
    NYPLid=models.IntegerField(unique=True)
    def __unicode__(self):
        return restaurant
    def __period__(self):#adapted from http://stackoverflow.com/questions/2272149/round-to-5or-other-number-in-python
    p=int(10*round(float(self.year)/10))
    if p < self.year:
        return "%s-%s"%(p,p+5)
    else:
        return "%s-%s"%(p-5,p)
    period=property(__period__) 

I have a view Search:

def search(request):
    errors = []
    form = SearchForm(request.GET)
    if form.is_valid():
        cd = form.cleaned_data
        row = cd['row']
        query = cd['query']
        dish_row_dict = {"dish_name":'name__icontains=query',
    "main_ingredient":"ingredient__icontains=query",
    "course":"course__iexact=query"
    }
        menu_row_dict = {"year":'year__exact=query',
    "period":'period__exact=query',
    "location":'location__icontains=query',
    "restaurant":"restaurant__icontains=query",
    }
        if row in dish_row_dict:
            dishes = MenuItem.objects.filter(eval(dish_row_dict[row]))
        elif row in menu_row_dict:
            dishes = MenuItem.objects.filter(eval("menu__%s"%(menu_row_dict[row])))
        return render_to_response("search_returns.html",{"dishes":dishes})
    return render_to_response("search_page.html",{"form":form})

I have a form SearchForm:

class SearchForm(forms.Form):
    row = forms.ChoiceField([("dish_name","Dish Name"),("year","Year"),
("period","Five-Year Period"),("location","Location"),
("main_ingredient","Main Ingredient"),("course","Course or Dish Type"),("restaurant","Restaurant"),])
    query = forms.CharField())

I'd like users to be able to choose one of the select options, and then do a query based on their choice (e.g., search by dish name if they select "Dish Name".) They way I'm doing things now, with a dictionary+eval() isn't working (I know, I know, eval = bad, but I wasn't sure how else to do it!)

I feel like this isn't an exotic or uncommon thing, but I'll be damned if I can find anything about it online. I suspect the answer has something to do with MultiValueField or something like that, but I really don't understand how to make that work.

Any help would be greatly appreciated.


回答1:


You can forget the =query and the eval() part and simply build a dict, and pass it as kwargs:

filter_keys = {
    # menuitem queries
    "dish_name":'name__icontains',
    "main_ingredient": "ingredient__icontains",
    "course": "course__iexact",
    # menu queries
    "year": 'menu__year__exact',
    "period": 'menu__period__exact',
    "location": 'menu__location__icontains',
    "restaurant": "menu__restaurant__icontains",
}

...

if row in filter_keys:
    dishes = MenuItem.objects.filter(**{filter_keys[row]: query})

The ** is a Python way of passing named parameters as a dict.



来源:https://stackoverflow.com/questions/13942096/change-query-parameter-via-select

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!