Ticket #8087: django-if-in-list.diff
File django-if-in-list.diff, 7.8 KB (added by , 16 years ago) |
---|
-
django/template/defaulttags.py
232 232 nodes.extend(self.nodelist_false.get_nodes_by_type(nodetype)) 233 233 return nodes 234 234 235 def __in_list_helper(self, context, list_, val_): 236 from django.db.models.query import QuerySet 237 val_ = val_.resolve(context, True) 238 list_ = list_.resolve(context, True) 239 if isinstance(list_, QuerySet): 240 if hasattr(val_, 'pk'): 241 if list_._result_cache: 242 in_list = val_ in list_ 243 else: 244 in_list = list_.filter(pk = val_.pk).count() > 0 245 else: 246 in_list = False 247 else: 248 in_list = val_ in list_ 249 return in_list 250 235 251 def render(self, context): 236 252 if self.link_type == IfNode.LinkTypes.or_: 237 253 for ifnot, bool_expr in self.bool_exprs: 238 try: 239 value = bool_expr.resolve(context, True) 240 except VariableDoesNotExist: 241 value = None 254 if isinstance(bool_expr, tuple): 255 val_, list_ = bool_expr 256 value = self.__in_list_helper(context, list_, val_) 257 else: 258 try: 259 value = bool_expr.resolve(context, True) 260 except VariableDoesNotExist: 261 value = None 242 262 if (value and not ifnot) or (ifnot and not value): 243 263 return self.nodelist_true.render(context) 244 264 return self.nodelist_false.render(context) 245 265 else: 246 266 for ifnot, bool_expr in self.bool_exprs: 247 try: 248 value = bool_expr.resolve(context, True) 249 except VariableDoesNotExist: 250 value = None 267 if isinstance(bool_expr, tuple): 268 val_, list_ = bool_expr 269 value = self.__in_list_helper(context, list_, val_) 270 else: 271 try: 272 value = bool_expr.resolve(context, True) 273 except VariableDoesNotExist: 274 value = None 251 275 if not ((value and not ifnot) or (ifnot and not value)): 252 276 return self.nodelist_false.render(context) 253 277 return self.nodelist_true.render(context) … … 778 802 There are some athletes and absolutely no coaches. 779 803 {% endif %} 780 804 805 ``if`` tags may also use ``in`` to test whether an object is (or is not) in a 806 list:: 807 808 {% if user in athlete_list %} 809 User is an athlete 810 {% endif %} 811 812 {% if user not in coach_list %} 813 User is not a coach 814 {% endif %} 815 816 {% if user in athlete_list and not user in coach_list %} 817 User is an athlete, but not a coach 818 {% endif %} 819 820 When using the ``in`` operator to test whether an element is in a QuerySet, 821 the behaviour depends upon whether the queryset has been executed already. 822 If it has already been executed, the behaviour is to search the result set 823 manually. If it has not been executed, or no result set is available, it will 824 filter down the QuerySet to check for just this item. 825 781 826 ``if`` tags do not allow ``and`` and ``or`` clauses with the same tag, 782 827 because the order of logic would be ambigous. For example, this is 783 828 invalid:: … … 810 855 raise TemplateSyntaxError, "'if' tags can't mix 'and' and 'or'" 811 856 for boolpair in boolpairs: 812 857 if ' ' in boolpair: 813 try: 814 not_, boolvar = boolpair.split() 815 except ValueError: 816 raise TemplateSyntaxError, "'if' statement improperly formatted" 817 if not_ != 'not': 818 raise TemplateSyntaxError, "Expected 'not' in if statement" 819 boolvars.append((True, parser.compile_filter(boolvar))) 858 elems = boolpair.split() 859 num_elems = len(elems) 860 if num_elems == 2: # parse 'not val' 861 not_, boolvar = elems 862 if not_ != 'not': 863 raise TemplateSyntaxError, "Expected 'not' in if statement" 864 boolvars.append((True, parser.compile_filter(boolvar))) 865 elif num_elems == 3: # parse 'val in list' 866 val_, in_, list_ = elems 867 if in_ != 'in': 868 raise TemplateSyntaxError, "Expected 'in' in if statement" 869 boolvars.append((False, (parser.compile_filter(val_), parser.compile_filter(list_)))) 870 elif num_elems == 4: # parse 'val not in list' and 'not val in list' 871 val_, not_, in_, list_ = elems 872 if val_ == 'not': 873 val_, not_ = not_, val_ 874 if not_ != 'not': 875 raise TemplateSyntaxError, "Expected 'not' in if statement" 876 elif in_ != 'in': 877 raise TemplateSyntaxError, "Expected 'in' in if statement" 878 boolvars.append((True, (parser.compile_filter(val_), parser.compile_filter(list_)))) 879 else: 880 raise TemplateSyntaxError, "Invalid if statement" 820 881 else: 821 882 boolvars.append((False, parser.compile_filter(boolpair))) 822 883 nodelist_true = parser.parse(('else', 'endif')) -
tests/regressiontests/templates/tests.py
554 554 'if-tag-or07': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'foo': True}, 'yes'), 555 555 'if-tag-or08': ("{% if foo or bar %}yes{% else %}no{% endif %}", {'bar': True}, 'yes'), 556 556 557 # IN 558 'if-tag-in01': ("{% if foo in list %}yes{% else %}no{% endif %}", {'foo': 'a', 'list': ['a', 'b', 'c']}, 'yes'), 559 'if-tag-in02': ("{% if foo in list %}yes{% else %}no{% endif %}", {'foo': 'x', 'list': ['a', 'b', 'c']}, 'no'), 560 'if-tag-in03': ("{% if not foo in list %}yes{% else %}no{% endif %}", {'foo': 'a', 'list': ['a', 'b', 'c']}, 'no'), 561 'if-tag-in04': ("{% if not foo in list %}yes{% else %}no{% endif %}", {'foo': 'x', 'list': ['a', 'b', 'c']}, 'yes'), 562 'if-tag-in05': ("{% if foo not in list %}yes{% else %}no{% endif %}", {'foo': 'a', 'list': ['a', 'b', 'c']}, 'no'), 563 'if-tag-in06': ("{% if foo not in list %}yes{% else %}no{% endif %}", {'foo': 'x', 'list': ['a', 'b', 'c']}, 'yes'), 564 'if-tag-in07': ("{% if foo and bar in list %}yes{% else %}no{% endif %}", {'foo': True, 'bar': 'a', 'list': ['a']}, 'yes'), 565 'if-tag-in08': ("{% if bar in list and foo %}yes{% else %}no{% endif %}", {'foo': True, 'bar': 'a', 'list': ['a']}, 'yes'), 566 'if-tag-in09': ("{% if foo and bar in list %}yes{% else %}no{% endif %}", {'foo': True, 'bar': 'b', 'list': ['a']}, 'no'), 567 'if-tag-in10': ("{% if bar in list and foo %}yes{% else %}no{% endif %}", {'foo': True, 'bar': 'b', 'list': ['a']}, 'no'), 568 'if-tag-in11': ("{% if foo or bar in list %}yes{% else %}no{% endif %}", {'foo': False, 'bar': 'a', 'list': ['a']}, 'yes'), 569 'if-tag-in12': ("{% if bar in list or foo %}yes{% else %}no{% endif %}", {'foo': False, 'bar': 'a', 'list': ['a']}, 'yes'), 570 'if-tag-in13': ("{% if foo or bar in list %}yes{% else %}no{% endif %}", {'foo': False, 'bar': 'b', 'list': ['a']}, 'no'), 571 'if-tag-in14': ("{% if bar in list or foo %}yes{% else %}no{% endif %}", {'foo': False, 'bar': 'b', 'list': ['a']}, 'no'), 572 557 573 # TODO: multiple ORs 558 574 559 575 # NOT