Using Filter on a list of objects?
I am trying to develop some functionality so that a user is able to query by a color. I have a form drop-down menu where the user can select one color type to appear. They are also able to leave it blank so that it returns all the available colors. I have my form returning the right results when a color type is selected. However, I am having problems displaying the results when no color is selected (because I'm using a filter). Here is part of my view if request['color'] == "---": # This means no color was selected mycolor = ColorCategory.objects.all() else: mycolor = request['color'] ... i = Choice.objects.get(id=h.id).style_set.filter(color_cat=mycolor) So, as you can probably see when a color type is selected then mycolor is set to request['color']. However, when a color is not selected then mycolor is set to 'ColorCategory.objects.all(). Then later in my view when I try to do a filter(color_cat=mycolor) It errors out because mycolor is equal to a list of ColorCategory objects. I need mycolor to equal any ColorCategory number. Does anybody know how to do that? Thanks --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
> if request['color'] == "---": # This means no color was > selected > mycolor = ColorCategory.objects.all() > else: > mycolor = request['color'] > ... > i = Choice.objects.get(id=h.id).style_set.filter(color_cat=mycolor) > > > > So, as you can probably see when a color type is selected then mycolor > is set to request['color']. However, when a color is not selected > then mycolor is set to 'ColorCategory.objects.all(). Then later in my > view when I try to do a > > filter(color_cat=mycolor) > > It errors out because mycolor is equal to a list of ColorCategory > objects. I need mycolor to equal any ColorCategory number. Does > anybody know how to do that? It sounds like you just want to filter selectively: NO_COLOR = '' styles = Choice.objects.get(id=h.id).style_set if 'color' in request and request['color'] <> NO_COLOR: styles = styles.filter(color_cat=request['color']) for style in styles: do_something(style) -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Tim, I added your code into my view. However, it seems to error out on me when I get to the line 'if 'color' in request and request['color'] <> NO_COLOR: '. The error says: KeyError at /rugs/searchresult/ '0 not found in either POST or GET' // Here is my view def searchresult(request): if request.method == 'POST': myprice = {} mysize = {} if request['price'] == "---": f = Price.objects.all() else: myprice['price_cat'] = request['price'] f = Price.objects.filter(**myprice) if request['size'] == "---": e = Size.objects.all() else: mysize['size_cat'] = request['size'] e = Size.objects.filter(**mysize) dict = {} for a in f: for b in e: g = Choice.objects.filter(price=a, size=b) for h in g: NO_COLOR = "---" styles = Choice.objects.get(id=h.id).style_set if 'color' in request and request['color'] <> NO_COLOR: styles = styles.filter(color_cat=request['color']) for j in styles: dict[j] = j return render_to_response('searchresult.html', {'s': dict}) / Also, when I do a 'assert False, styles' after the line 'styles = Choice.objects.get(id=h.id).style_set' I get the following error: ' Don't I want styles to bring back a style? /// Thanks for you help On Aug 7, 3:33 pm, Tim Chase <[EMAIL PROTECTED]> wrote: > > if request['color'] == "---": # This means no color was > > selected > > mycolor = ColorCategory.objects.all() > > else: > > mycolor = request['color'] > > ... > > i = Choice.objects.get(id=h.id).style_set.filter(color_cat=mycolor) > > > > > > So, as you can probably see when a color type is selected then mycolor > > is set to request['color']. However, when a color is not selected > > then mycolor is set to 'ColorCategory.objects.all(). Then later in my > > view when I try to do a > > >filter(color_cat=mycolor) > > > It errors out because mycolor is equal to alistof ColorCategory > > objects. I need mycolor to equal any ColorCategory number. Does > > anybody know how to do that? > > It sounds like you just want tofilterselectively: > >NO_COLOR = '' >styles = Choice.objects.get(id=h.id).style_set >if 'color' in request and request['color'] <> NO_COLOR: > styles = styles.filter(color_cat=request['color']) > >for style in styles: > do_something(style) > > -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Greg skrev: > Tim, > I added your code into my view. However, it seems to error out on me > when I get to the line 'if 'color' in request and request['color'] <> > NO_COLOR: '. The error says: > > KeyError at /rugs/searchresult/ > '0 not found in either POST or GET' > The error message indicates that you did something equivalent to request[0] Are you sure you didn't do this: if 'color' in request and request[color] <> NO_COLOR: or this: if 'color' in request and request[color <> NO_COLOR]: ? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Nis, Thanks for the help. We'll I got my view to work for website visitors searching by any combintation of Size, Price, and Color. My code is not the most efficient and I wonder how the performance is going to be once I add more products and take it off of developmental version and into a production environment. If anybody has any suggestions on how to make the code more optimized would be appreciated. Here is my view: def searchresult(request): if request.method == 'POST': myprice = {} mysize = {} if request['price'] == "---": #Check to see if a price was selected to filter by f = Price.objects.all() else: myprice['price_cat'] = request['price'] f = Price.objects.filter(**myprice) if request['size'] == "---": #Check to see if a size was selected to filter by e = Size.objects.all() else: mysize['size_cat'] = request['size'] e = Size.objects.filter(**mysize) dict = {} for a in f: #Loop through the selected prices . Get value from above for b in e:#Loop through the selected sizes. Get value from above g = Choice.objects.filter(price=a, size=b) for h in g: NO_COLOR = "---" styles = Choice.objects.get(id=h.id).style_set.all() if request['color'] <> NO_COLOR: #check to see if a color to filter by was selected styles = styles.filter(color_cat=request['color']) for j in styles: # check to see if the style is already in the dictionary num = 0 for a in dict: if a == j: num = 1 if num == 0: dict[j] = j else: for p in styles: # check to see if the style is already in the dictionary num = 0 for a in dict: if a == p: num = 1 if num == 0: dict[p] = p#assert False, styles return render_to_response('searchresult.html', {'s': dict}) / Please let me know on a scale of 1-10 on how (good/bad) this code is. Thanks On Aug 8, 6:43 am, Nis Jørgensen <[EMAIL PROTECTED]> wrote: > Greg skrev:> Tim, > > I added your code into my view. However, it seems to error out on me > > when I get to the line 'if 'color' in request and request['color'] <> > > NO_COLOR: '. The error says: > > > KeyError at /rugs/searchresult/ > > '0 not found in either POST or GET' > > The error message indicates that you did something equivalent to > request[0] > > Are you sure you didn't do this: > > if 'color' in request and request[color] <> NO_COLOR: > > or this: > > if 'color' in request and request[color <> NO_COLOR]: > > ? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Why are you doing request['price'] ? Do you perhaps mean request.POST['price'] or request.GET['price'] ? :) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Collin, Doesn't request['price'] return the same as request.POST['price']? assert False, request['price'] assert False, request.POST['price'] They both return 1 (in my example) I guess it would be better to make sure it's the price variable that's been posted. I've made the change. Thanks On Aug 8, 2:54 pm, Collin Grady <[EMAIL PROTECTED]> wrote: > Why are you doing request['price'] ? > > Do you perhaps mean request.POST['price'] or request.GET['price'] ? :) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
> If anybody has any suggestions on how to make the code more > optimized would be appreciated. Here is my view: First, a style issue: it's considered bad form to shadow the python built-in "dict" by using a variable with the same name. Second, my eyes are bleeding from the convolution of that code. If I understand what you're trying to do, you simply want to filter the Choice objects by price, size and color if they've been specified. Thus, wouldn't you be able to do something like c = Choice.objects.get(id=h.id).style_set.all() NOT_PICKED = '--' if 'price' in request and request['price'] <> NOT_PICKED: c = c.filter(price=request['price']) if 'size' in request and request['size'] <> NOT_PICKED: c = c.filter(size=request['size']) if 'color' in request and request['color'] <> NOT_PICKED: c = c.filter(color=request['color']) return render_to_response('searchresult.html', { 'results': c }) which is a heckuva lot easier to read and likely piles better in terms of performance (no looping, let alone nested looping). If your request vars have multiple-selections for a given value (an iterable via the getlist() method of the QueryDict), you can smash them together: #at the top from operator import or_ #change each "c = c.filter(...)" line above to this form: c = c.filter(reduce(or_, [ Q(size=s) for s in request.getlist('size') ])) which "or"s together Q() objects for each individual size before passing it to the filter. It's not a great remedy in the "eyes bleeding" department, but both make the logic a bit easier to follow the pattern: if they submitted a {{ field }}, filter the Objects by {{ field }} As for request[varname] vs. request.POST[varname] vs. request.GET[varname] I'm not sure what the difference is (other than the obvious diff between GET & POST) without reading the code, but it should work unless you explicitly want something different. For filtering/searching purposes, I tend to prefer GET parameters because it's easy to bookmark the results if you want or send the link to someone so they can see the same results. -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Tim, Thanks for the reply. Very helpful. In the past I did try the statement: if 'price' in request and request['price'] <> NOT_PICKED: However when that line was accessed I would get the following error: KeyError at /rugs/searchresult/ '0 not found in either POST or GET' / I think it has something to do with 'request'. Because when I take that out and just use 'if 'price' in request['price'] <> NOT_PICKED: ' then it doesn't error out. Any suggestions as to why that's happening? Thanks On Aug 8, 4:28 pm, Tim Chase <[EMAIL PROTECTED]> wrote: > > If anybody has any suggestions on how to make the code more > > optimized would be appreciated. Here is my view: > > First, a style issue: it's considered bad form to shadow the > python built-in "dict" by using a variable with the same name. > > Second, my eyes are bleeding from the convolution of that code. > > If I understand what you're trying to do, you simply want to > filter the Choice objects by price, size and color if they've > been specified. Thus, wouldn't you be able to do something like > >c = Choice.objects.get(id=h.id).style_set.all() >NOT_PICKED = '--' >if 'price' in request and request['price'] <> NOT_PICKED: > c = c.filter(price=request['price']) >if 'size' in request and request['size'] <> NOT_PICKED: > c = c.filter(size=request['size']) >if 'color' in request and request['color'] <> NOT_PICKED: > c = c.filter(color=request['color']) >return render_to_response('searchresult.html', { > 'results': c > }) > > which is a heckuva lot easier to read and likely piles better in > terms of performance (no looping, let alone nested looping). > > If your request vars have multiple-selections for a given value > (an iterable via the getlist() method of the QueryDict), you can > smash them together: > >#at the top >from operator import or_ > >#change each "c = c.filter(...)" line above to this form: >c = c.filter(reduce(or_, [ > Q(size=s) for s in request.getlist('size') > ])) > > which "or"s together Q() objects for each individual size before > passing it to the filter. It's not a great remedy in the "eyes > bleeding" department, but both make the logic a bit easier to > follow the pattern: > >if they submitted a {{ field }}, > filter the Objects by {{ field }} > > As for request[varname] vs. request.POST[varname] vs. > request.GET[varname] I'm not sure what the difference is (other > than the obvious diff between GET & POST) without reading the > code, but it should work unless you explicitly want something > different. For filtering/searching purposes, I tend to prefer > GET parameters because it's easy to bookmark the results if you > want or send the link to someone so they can see the same results. > > -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
> Thanks for the reply. Very helpful. In the past I did try the > statement: > > if 'price' in request and request['price'] <> NOT_PICKED: > > > > However when that line was accessed I would get the following error: > > KeyError at /rugs/searchresult/ > '0 not found in either POST or GET' > > / > > I think it has something to do with 'request'. Because when I take > that out and just use 'if 'price' in request['price'] <> NOT_PICKED: ' > then it doesn't error out. > > Any suggestions as to why that's happening? Um...because it does nothing like what you expect it to? :) I'd try the earlier suggestion of if ('price' in request.GET) and \ (request.GET['price'] <> NOT_PICKED): where GET can be converted to POST corresponding to whichever method the form is using to send the filter criteria. (Parens added around the two "and"ed clauses for clarity, though they shouldn't make a difference). If the "in" returns true, the second clause should not fail. -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Tim, Why do I need to do the following: if ('price' in request.POST) and (request.POST['price'] <> NOT_PICKED): instead of if request.POST['price'] <> NOT_PICKED: Everytime the form is submitted a value for price is sent to the view. If no price was selected then the value of request.POST['price'] is equal to '-'. So price will always be submitted. Thanks On Aug 8, 5:23 pm, Tim Chase <[EMAIL PROTECTED]> wrote: > > Thanks for the reply. Very helpful. In the past I did try the > > statement: > > > if 'price' in request and request['price'] <> NOT_PICKED: > > > > > > However when that line was accessed I would get the following error: > > > KeyError at /rugs/searchresult/ > > '0 not found in either POST or GET' > > > / > > > I think it has something to do with 'request'. Because when I take > > that out and just use 'if 'price' in request['price'] <> NOT_PICKED: ' > > then it doesn't error out. > > > Any suggestions as to why that's happening? > > Um...because it does nothing like what you expect it to? :) > > I'd try the earlier suggestion of > > if ('price' in request.GET) and \ > (request.GET['price'] <> NOT_PICKED): > > where GET can be converted to POST corresponding to whichever > method the form is using to send the filter criteria. (Parens > added around the two "and"ed clauses for clarity, though they > shouldn't make a difference). If the "in" returns true, the > second clause should not fail. > > -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
> Why do I need to do the following: > > if ('price' in request.POST) and (request.POST['price'] <> > NOT_PICKED): > > instead of > > if request.POST['price'] <> NOT_PICKED: In the event that for some reason that field hasn't been sent along. This could be some other site using you as a web service, this could be your own mistake...in general it's just good programming practice to not explode if something goes unexpected. These could be rewritten as if request.POST.get('price', NOT_PICKED) <> NOT_PICKED: if you want to shorten it some. -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Tim, I think you just got my color search to work (Thank You). Here is the code: NO_COLOR = "---" styles = Choice.objects.get(id=h.id).style_set.all() if ('color' in request.POST) and (request.POST['color'] <> NO_COLOR): styles = styles.filter(color_cat=request['color']) for u in styles: dict[u] = u I did notice that whenever I do a search for just the color 'brown'. Then the result set will bring back the same style however many different sizes that are in the style. So if an area rug sells two choices (2'x3' 39.00, 4'x6' 149.00). Then that style will show up twice in the result set. Is there anyway better to filter out the styles that have already been added to the dictionary. My previous code worked..but not sure it's the best way to do it. Here it is: num = 0 for a in dict: if a == j: # 'j' being the name of the style and 'a' is the name of the style that is already in the dictionary num = 1 if num == 0: dict[j] = j /// I know that there is a distinct() method, but I think that only works over QuerySet's of multiple tables. Thanks On Aug 8, 6:56 pm, Tim Chase <[EMAIL PROTECTED]> wrote: > > Why do I need to do the following: > > > if ('price' in request.POST) and (request.POST['price'] <> > > NOT_PICKED): > > > instead of > > > if request.POST['price'] <> NOT_PICKED: > > In the event that for some reason that field hasn't been sent > along. This could be some other site using you as a web service, > this could be your own mistake...in general it's just good > programming practice to not explode if something goes unexpected. > > These could be rewritten as > >if request.POST.get('price', NOT_PICKED) <> NOT_PICKED: > > if you want to shorten it some. > > -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Greg skrev: > Nis, > Thanks for the help. We'll I got my view to work for website visitors > searching by any combintation of Size, Price, and Color. My code is > not the most efficient and I wonder how the performance is going to be > once I add more products and take it off of developmental version and > into a production environment. > > If anybody has any suggestions on how to make the code more optimized > would be appreciated. Here is my view: > What Tim said, and this: It would make your code much more readable if you used meaningful variable names. Python makes the need for explicit looping a lot less frequent than most other programming languages. Whenever you are looping through a list/dictionary and comparing each value to some other value, chance is that you should really be using "if a in b". In general, dont use my_dictionary = {} my_dictionary[x] = x Use myset = set() myset.add(x) And finally: Don't Repeat Yourself. Whenever you have two blocks of code that looks almost the same, try to refactor your code. Example: > NO_COLOR = "---" > styles = > Choice.objects.get(id=h.id).style_set.all() > if request['color'] <> NO_COLOR: > styles = > styles.filter(color_cat=request['color']) > for j in styles: > num = 0 > for a in dict: > if a == j: > num = 1 > if num == 0: > dict[j] = j > else: > for p in styles: > num = 0 > for a in dict: > if a == p: > num = 1 > if num == 0: > dict[p] = > p#assert False, styles > First step: Rename variables so they match in the two branches: NO_COLOR = "---" styles = Choice.objects.get(id=h.id).style_set.all() if request['color'] <> NO_COLOR: styles = styles.filter(color_cat=request['color']) for style in styles: num = 0 for key in dict: if key == style: num = 1 if num == 0: dict[style] = style else: for style in styles: num = 0 for key in dict: if key == style: num = 1 if num == 0: dict[style] = style Second step: Move the common block out of the conditional NO_COLOR = "---" styles = Choice.objects.get(id=h.id).style_set.all() if request['color'] <> NO_COLOR: styles = styles.filter(color_cat=request['color']) for style in styles: num = 0 for key in dict: if key == style: num = 1 if num == 0: dict[style] = style Third step: Replace the logic "If the key is not in the dictionary, put it there" with "put the key in the dictionary". Since the value associated with the key is
Re: Using Filter on a list of objects?
> NO_COLOR = "---" > styles = Choice.objects.get(id=h.id).style_set.all() > if ('color' in request.POST) and (request.POST['color'] <> NO_COLOR): > styles = styles.filter(color_cat=request['color']) > for u in styles: > dict[u] = u > > > > I did notice that whenever I do a search for just the color 'brown'. > Then the result set will bring back the same style however many > different sizes that are in the style. So if an area rug sells two > choices (2'x3' 39.00, 4'x6' 149.00). Then that style will show up > twice in the result set. Is there anyway better to filter out the > styles that have already been added to the dictionary. My previous > code worked..but not sure it's the best way to do it. Here it is: > > num = 0 > for a in dict: > if a == j: # 'j' being the name of the style and 'a' is the name of > the style that is already in the dictionary > num = 1 > if num == 0: > dict[j] = j I second the suggestion by Nis to make meaningful variable names, as well as the suggestion to use sets rather than abusing a dictionary (and tromping on the namespace with "dict"...just got bitten by this yesterday, a "zip"-code variable shadowed the built-in zip() command causing some confusing errors) It looks like you could just do something like results = Choice.objects.get(id=h.id).style_set.all() # filter results results = set(results) I'm not sure on the performance of set creation, so you might compare the results with results = set(list(results)) or results = set(tuple(results)) -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Tim and Nis, Okay thanks for the help. My view is definitily better now than before. Here is my new view def searchresult(request): if request.method == 'POST': myset = set() NOT_PICKED = "---" y = Choice.objects.all() if ('price' in request.POST and request.POST['price'] <> NOT_PICKED): y = y.filter(price__price_cat=request['price']) if ('size' in request.POST and request.POST['size'] <> NOT_PICKED): y = y.filter(size__size_cat=request['size']) for q in y: styles = Choice.objects.get(id=q.id).style_set.all() if ('color' in request.POST) and (request.POST['color'] <> NOT_PICKED): styles = styles.filter(color_cat=request['color']) for style in styles: myset.add(style) if myset == set([]): return render_to_response('searchresult_none.html', {'s': "No product available"}) else: return render_to_response('searchresult.html', {'s': myset}) Does that look any better? I have two issues with this. 1) Is there anyway to get it so that I don't have to use the following for loop: for style in styles: myset.add(style) 2) Is still adds duplicate products. If a product contains two choices that have a price of 149 and 199. Then when a user searches by price only (100-199) then the product is displayed twice in the result set. Thank you SO much for your help!!! This is my first time developing in Python and I'm learning quite a bit. On Aug 9, 8:37 am, Tim Chase <[EMAIL PROTECTED]> wrote: > > NO_COLOR = "---" > > styles = Choice.objects.get(id=h.id).style_set.all() > > if ('color' in request.POST) and (request.POST['color'] <> NO_COLOR): > > styles = styles.filter(color_cat=request['color']) > > for u in styles: > > dict[u] = u > > > > > > I did notice that whenever I do a search for just the color 'brown'. > > Then the result set will bring back the same style however many > > different sizes that are in the style. So if an area rug sells two > > choices (2'x3' 39.00, 4'x6' 149.00). Then that style will show up > > twice in the result set. Is there anyway better to filter out the > > styles that have already been added to the dictionary. My previous > > code worked..but not sure it's the best way to do it. Here it is: > > > num = 0 > > for a in dict: > >if a == j: # 'j' being the name of the style and 'a' is the name of > > the style that is already in the dictionary > >num = 1 > >if num == 0: > >dict[j] = j > > I second the suggestion by Nis to make meaningful variable names, > as well as the suggestion to use sets rather than abusing a > dictionary (and tromping on the namespace with "dict"...just got > bitten by this yesterday, a "zip"-code variable shadowed the > built-in zip() command causing some confusing errors) > > It looks like you could just do something like > >results = Choice.objects.get(id=h.id).style_set.all() ># filter results >results = set(results) > > I'm not sure on the performance of set creation, so you might > compare the results with > > results = set(list(results)) > > or > > results = set(tuple(results)) > > -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Ok...I'm looking more into sets. Whenever I do a search for products under 3' width. This is what I get when I do a 'assert False, myset': AssertionError at /rugs/searchresult/ set([, , , , , , , ]) I don't understand how the 2 entries of '' and '' are getting put into the list. // I ran some examples through in my python prompt: >>> s = set([1,2,3,4,5,6]) >>> s.add(7) >>> s set([1, 2, 3, 4, 5, 6, 7]) >>> s.add(7) >>> s set([1, 2, 3, 4, 5, 6, 7]) >>> s2 = set([1,2,3,4,5]) >>> s2.add(9) >>> s2 set([1, 2, 3, 4, 5, 9]) >>> s2.add(5) >>> s2 set([1, 2, 3, 4, 5, 9]) I created the same thing using the s2 variable and the s2.add(5) statement wasn't added to the list. It makes me wonder if the two '' and ' objects are different, because based on my example only one of each should be in the list. Thanks On Aug 9, 12:17 pm, Greg <[EMAIL PROTECTED]> wrote: > Tim and Nis, > Okay thanks for the help. My view is definitily better now than > before. Here is my new view > > def searchresult(request): > if request.method == 'POST': > myset = set() > NOT_PICKED = "---" > y = Choice.objects.all() > if ('price' in request.POST and request.POST['price'] <> > NOT_PICKED): > y = y.filter(price__price_cat=request['price']) > if ('size' in request.POST and request.POST['size'] <> > NOT_PICKED): > y = y.filter(size__size_cat=request['size']) > for q in y: > styles = Choice.objects.get(id=q.id).style_set.all() > if ('color' in request.POST) and > (request.POST['color'] <> > NOT_PICKED): > styles = > styles.filter(color_cat=request['color']) > for style in styles: > myset.add(style) > if myset == set([]): > return render_to_response('searchresult_none.html', {'s': "No > product available"}) > else: > return render_to_response('searchresult.html', {'s': myset}) > > > > Does that look any better? I have two issues with this. > > 1) Is there anyway to get it so that I don't have to use the following > for loop: > > for style in styles: > myset.add(style) > > 2) Is still adds duplicate products. If a product contains two > choices that have a price of 149 and 199. Then when a user searches > by price only (100-199) then the product is displayed twice in the > result set. > > > > Thank you SO much for your help!!! This is my first time developing > in Python and I'm learning quite a bit. > > On Aug 9, 8:37 am, Tim Chase <[EMAIL PROTECTED]> wrote: > > > > NO_COLOR = "---" > > > styles = Choice.objects.get(id=h.id).style_set.all() > > > if ('color' in request.POST) and (request.POST['color'] <> NO_COLOR): > > > styles = styles.filter(color_cat=request['color']) > > > for u in styles: > > > dict[u] = u > > > > > > > > I did notice that whenever I do a search for just the color 'brown'. > > > Then the result set will bring back the same style however many > > > different sizes that are in the style. So if an area rug sells two > > > choices (2'x3' 39.00, 4'x6' 149.00). Then that style will show up > > > twice in the result set. Is there anyway better to filter out the > > > styles that have already been added to the dictionary. My previous > > > code worked..but not sure it's the best way to do it. Here it is: > > > > num = 0 > > > for a in dict: > > >if a == j: # 'j' being the name of the style and 'a' is the name of > > > the style that is already in the dictionary > > >num = 1 > > >if num == 0: > > >dict[j] = j > > > I second the suggestion by Nis to make meaningful variable names, > > as well as the suggestion to use sets rather than abusing a > > dictionary (and tromping on the namespace with "dict"...just got > > bitten by this yesterday, a "zip"-code variable shadowed the > > built-in zip() command causing some confusing errors) > > > It looks like you could just do something like > > >results = Choice.objects.get(id=h.id).style_set.all() > ># filter results > >results = set(results) > > > I'm not sure on the performance of set creation, so you might > > compare the results with > > > results = set(list(results)) > > > or > > > results = set(tuple(results)) > > > -tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Try changing this fragment: for q in y: styles = Choice.objects.get(id=q.id).style_set.all() to something like this: choice_ids = [c.id for c in y] styles = Style.objects.filter(choice__id__in=choice_ids).distinct() If that works, you shouldn't need a set or a map to weed out duplicates. Incidentally, set() doesn't do the trick for you because you get two different instances of the Style model class. Granted that they both represent the same row of data in your DB but they are still two different Python object instances unless you add comparison methods in your Style class that make it seem to Python that they are the same object. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
RajeshD, I implemented what you said. Here is my attempt: choice_ids = [c.id for c in y] styles = Style.objects.filter(sandp__choice__in=choice_ids) if ('color' in request.POST) and (request.POST['color'] <> NOT_PICKED): styles = styles.filter(color_cat=request['color']) myset.add(styles) assert False, myset When it encounters the 'assert False, myset'. I see a set within a list within a list: AssertionError at /rugs/searchresult/ set([[, , , , ]]) // It's bringing back the right records (not filtered though), however they are not visible. Probably because of a list within a list. Thanks On Aug 9, 4:29 pm, RajeshD <[EMAIL PROTECTED]> wrote: > Try changing this fragment: > > for q in y: >styles = Choice.objects.get(id=q.id).style_set.all() > > to something like this: > > choice_ids = [c.id for c in y] > styles = Style.objects.filter(choice__id__in=choice_ids).distinct() > > If that works, you shouldn't need a set or a map to weed out > duplicates. > > Incidentally, set() doesn't do the trick for you because you get two > different instances of the Style model class. Granted that they both > represent the same row of data in your DB but they are still two > different Python object instances unless you add comparison methods in > your Style class that make it seem to Python that they are the same > object. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Hi Greg, > myset.add(styles) You don't need the myset part anymore. > It's bringing back the right records (not filtered though), however > they are not visible. Probably because of a list within a list. Right. I assume that you were using the set idiom to eliminate duplicate records of Style. Since the new query does all of that for you, you can just directly use 'styles' where you previously needed 'myset'. In other words, this: return render_to_response('searchresult.html', {'s': myset}) would change to: return render_to_response('searchresult.html', {'s': styles}) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
AlrightI'm sorry guys this is taking so long to get figured out. I'm trying my best. It a lot shorter than when I started and I'm no longer using any for statements. Here is my view: def searchresult(request): if request.method == 'POST': NOT_PICKED = "---" y = Choice.objects.all() if ('price' in request.POST and request.POST['price'] <> NOT_PICKED): y = y.filter(price__price_cat=request['price']) if ('size' in request.POST and request.POST['size'] <> NOT_PICKED): y = y.filter(size__size_cat=request['size']) choice_ids = [c.id for c in y] styles = Style.objects.filter(sandp__choice__in=choice_ids).distinct() if ('color' in request.POST) and (request.POST['color'] <> NOT_PICKED): styles = styles.filter(color_cat=request['color']) return render_to_response('searchresult.html', {'s': styles}) I'm having a couple of problems with this code. First is the following code: y = y.filter(price__price_cat=request['price']) I currently have two prices in the 200-299 range (249 and 299). If the user does a search for price between 200-299 then the only thing this filter returns is the first one. I never returns more than one. For example when i do a assert False, y after the statement above I get: AssertionError at /rugs/searchresult/ [, )>] I do have a record in my choice table that has 249 as the price. /// Second. The following code doesn't seem to work correctly choice_ids = [c.id for c in y] styles = Style.objects.filter(sandp__choice__in=choice_ids).distinct() This returns [] even though in myexample choice_ids = [7] Here is my Style Class: class Style(models.Model): name = models.CharField(maxlength=200, core=True) color = models.CharField(maxlength=100) color_cat = models.ForeignKey(ColorCategory) image = models.ImageField(upload_to='site_media/') mimage = models.ImageField(upload_to='site_media/thumbnails', editable=False) simage = models.ImageField(upload_to='site_media/thumbnails', editable=False) theslug = models.SlugField(prepopulate_from=('name',)) manufacturer = models.ForeignKey(Manufacturer) collection = models.ForeignKey(Collection, edit_inline=models.TABULAR, num_in_admin=6) sandp = models.ManyToManyField(Choice) // Thanks again for the help On Aug 9, 5:52 pm, RajeshD <[EMAIL PROTECTED]> wrote: > Hi Greg, > > > myset.add(styles) > > You don't need the myset part anymore. > > > It's bringing back the right records (not filtered though), however > > they are not visible. Probably because of a list within a list. > > Right. I assume that you were using the set idiom to eliminate > duplicate records of Style. Since the new query does all of that for > you, you can just directly use 'styles' where you previously needed > 'myset'. In other words, this: > > return render_to_response('searchresult.html', {'s': myset}) > > would change to: > > return render_to_response('searchresult.html', {'s': styles}) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
RajeshD, Tim, and Nis, We'll I think I got it working. I changed the following line: Style.objects.filter(sandp__choice__in=choice_ids).distinct() to Style.objects.filter(sandp__in=choice_ids).distinct() That brought back the correct records. / Also, the problem with: y = y.filter(price__price_cat=request['price']) Actually, wasn't a problem. There wasn't a choice that contained 249 as the price Here is the final version of my view: def searchresult(request): if request.method == 'POST': NOT_PICKED = "---" y = Choice.objects.all() if ('price' in request.POST and request.POST['price'] <> NOT_PICKED): y = y.filter(price__price_cat__exact=request['price']) if ('size' in request.POST and request.POST['size'] <> NOT_PICKED): y = y.filter(size__size_cat__exact=request['size']) choice_ids = [c.id for c in y] styles = Style.objects.filter(sandp__in=choice_ids).distinct() if ('color' in request.POST) and (request.POST['color'] <> NOT_PICKED): styles = styles.filter(color_cat=request['color']) return render_to_response('searchresult.html', {'s': styles}) / Hopefully, it's at least readable now. Thanks again to everybody that helped! On Aug 10, 8:48 am, RajeshD <[EMAIL PROTECTED]> wrote: > Hi Greg, > > Please see some notes below. > > > def searchresult(request): > > if request.method == 'POST': > > NOT_PICKED = "---" > > y = Choice.objects.all() > > if ('price' in request.POST and request.POST['price'] <> > > NOT_PICKED): > > You could simplify idioms like the above into a single condition: > > if request.POST.get('price', None) <> NOT_PICKED: > > > > > y = y.filter(price__price_cat=request['price']) > > if ('size' in request.POST and request.POST['size'] <> > > NOT_PICKED): > > y = y.filter(size__size_cat=request['size']) > > choice_ids = [c.id for c in y] > > styles = > > Style.objects.filter(sandp__choice__in=choice_ids).distinct() > > if ('color' in request.POST) and (request.POST['color'] <> > > NOT_PICKED): > > styles = styles.filter(color_cat=request['color']) > > return render_to_response('searchresult.html', {'s': styles}) > > > > > > I'm having a couple of problems with this code. First is the > > following code: > > > y = y.filter(price__price_cat=request['price']) > > Can you paste your entire model so we can see how you have defined > Choices, Price, Color, etc? ManyToManyFields get trickier when you > need to join multiple tables. I suspect that's what is causing this > problem for you. > > > I currently have two prices in the 200-299 range (249 and 299). If > > the user does a search for price between 200-299 then the only thing > > this filter returns is the first one. I never returns more than one. > > For example when i do a assert False, y after the statement above I > > get: > > > AssertionError at /rugs/searchresult/ > > [, )>] > > > I do have a record in my choice table that has 249 as the price. > > Instead of using assertions and debug print statements, it will save > you a lot of time if you dropped into a shell (python manage.py shell) > and ran a few of these querysets directly in there. View->Browse->Fix->Repeat > takes much longer in situations where you are just looking to > > create the right query sets. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---
Re: Using Filter on a list of objects?
Hi Greg, Please see some notes below. > def searchresult(request): > if request.method == 'POST': > NOT_PICKED = "---" > y = Choice.objects.all() > if ('price' in request.POST and request.POST['price'] <> > NOT_PICKED): You could simplify idioms like the above into a single condition: if request.POST.get('price', None) <> NOT_PICKED: > y = y.filter(price__price_cat=request['price']) > if ('size' in request.POST and request.POST['size'] <> > NOT_PICKED): > y = y.filter(size__size_cat=request['size']) > choice_ids = [c.id for c in y] > styles = > Style.objects.filter(sandp__choice__in=choice_ids).distinct() > if ('color' in request.POST) and (request.POST['color'] <> > NOT_PICKED): > styles = styles.filter(color_cat=request['color']) > return render_to_response('searchresult.html', {'s': styles}) > > > > I'm having a couple of problems with this code. First is the > following code: > > y = y.filter(price__price_cat=request['price']) Can you paste your entire model so we can see how you have defined Choices, Price, Color, etc? ManyToManyFields get trickier when you need to join multiple tables. I suspect that's what is causing this problem for you. > I currently have two prices in the 200-299 range (249 and 299). If > the user does a search for price between 200-299 then the only thing > this filter returns is the first one. I never returns more than one. > For example when i do a assert False, y after the statement above I > get: > > AssertionError at /rugs/searchresult/ > [, )>] > > I do have a record in my choice table that has 249 as the price. Instead of using assertions and debug print statements, it will save you a lot of time if you dropped into a shell (python manage.py shell) and ran a few of these querysets directly in there. View->Browse->Fix- >Repeat takes much longer in situations where you are just looking to create the right query sets. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~--~~~~--~~--~--~---