Should there be a "is" comperator: {% if A is B %}?

177 views
Skip to first unread message

Gregor Müllegger

unread,
Apr 9, 2014, 5:53:56 PM4/9/14
to django-d...@googlegroups.com
Hi,

I recently had the need to check for "value is not True" (as an identity check, not
on equality) in django-floppyforms. The template should generate the HTML
attributes for an HTML element from a python dict, but leave out the attribute
value if the dict's value is True. Like:

  {'required': True, 'name': 'fieldname'} => <input required name="fieldname" />

If there would be an "is" identity check in the Django template language it
would look like:

    {% for name, value in attrs.items %} {{ name }}{% if value is not True %}="{{ value }}"{% endif %}{% endfor %}

But since there is none, the if case looks now like this:

    {% if value|stringformat:"s" != "True" or value != 1 %}

See: https://github.com/gregmuellegger/django-floppyforms/blob/master/floppyforms/templates/floppyforms/attrs.html

The template previously checked with {% if not value %}, but that would break if
you pass in the integer 1. Since "True == 1", but "True is not 1".


I do get why there is no "is" comperator in the DTL yet. It might be confused
with the equality check by designers that don't know the underlying concepts of
equality and identity. And I think that's totally reasonable.

However I still want to bring this up since there is this real usecase I
described above. Ofcourse I could introduce a custom filter or tag to scratch
that itch, but IMO this is something very fundamental that I would expect to have
as a python developer.

So here are a few solutions I can think of:

1. Have an "is" and "is not" comperator in the {% if %} tag. Could lead to confusion.

2. Have a "===" and "!==" comperator in the {% if %} tag. This is something nearer to
   Javascript than python and makes it clear that it's different to == but would
   still confuse someone who did't read the DTL documentation.

3. Have a "is_identical" builtin filter. So it would be {% if not value|is_identical:True %}.
 

My favourite is option 3. It's very readable and doesn't introduce possible
confusions for non-python programmers.

What is your opinion on this?


Gregor

Tino de Bruijn

unread,
Apr 10, 2014, 5:41:33 AM4/10/14
to django-d...@googlegroups.com
Wouldn't this be easier?:

{'required': "", 'name': 'fieldname'} => <input required name="fieldname" />

{% for name, value in attrs.items %} {{ name }}{% if value %}="{{ value }}"{% endif %}{% endfor %}


Tino


--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CALjSGCPsE3TTr2zzkUZboADpSOCymCue1HVC_SqB6mLMfpfwWA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Gregor Müllegger

unread,
Apr 10, 2014, 7:11:41 PM4/10/14
to django-d...@googlegroups.com
Hi,

thanks for your input. Unfortunatelly this would fail for int(0):

{'value': 0} => <input value>

Gregor


Łukasz Rekucki

unread,
Apr 11, 2014, 1:44:44 AM4/11/14
to django-developers
On 11 April 2014 01:11, Gregor Müllegger <gre...@muellegger.de> wrote:
> Hi,
>
> thanks for your input. Unfortunatelly this would fail for int(0):

Not if you encode all values to strings before passing to the
template, so it's "0" instead of 0.

>
> {'value': 0} => <input value>
>
> Gregor
>
>
> 2014-04-10 11:41 GMT+02:00 Tino de Bruijn <tin...@gmail.com>:
>
>> Wouldn't this be easier?:
>>
>> {'required': "", 'name': 'fieldname'} => <input required name="fieldname"
>> />
>>
>> {% for name, value in attrs.items %} {{ name }}{% if value %}="{{ value
>> }}"{% endif %}{% endfor %}
>>
>>
>> Tino
>>

--
Łukasz Rekucki

Gregor Müllegger

unread,
Apr 11, 2014, 4:35:05 AM4/11/14
to django-d...@googlegroups.com
Casting to strings would make this example work. But will break in other cases:

dict((key, str(val)) for key, val in {'value': None}.items())
  => <input value="None">


I don't want to say that this problem is impossible to solve without a "is" check in the templates, I only want to point out that this basic comparison that is very handy in python on many ocassions is not available in the template. And having something like this in core might just make the template language a bit rounder and nicer to use for pythonistas.

· Gregor ·


--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.

Justin Holmes

unread,
Apr 13, 2014, 12:48:45 PM4/13/14
to django-developers

I think I'm +1.  This seems to add some signal with zero noise.

Shai Berger

unread,
Apr 13, 2014, 5:24:12 PM4/13/14
to django-d...@googlegroups.com
Hi all,

For the use case brought up originally, note
https://code.djangoproject.com/ticket/20684

In that spirit, I think the better solution for the more general case brought
here is a filter, say tag_attr, which takes a name and a value and renders them
appropriately:

{% for name, value in attrs.items %} {{ name|tag_attr:value }}{% endfor %}

I'm not sure if this needs to be a built-in filter, but I wouldn't object to
it. And unless there are other use cases for the "is" comparator, I'm -0 on
that.

Shai.
Reply all
Reply to author
Forward
0 new messages