On Feb 1, 10:45 pm, NENAD CIKIC <nenad.ci...@gmail.com> wrote:
> Hello, the subject expresses my discomfort with certain python
> characteristics, given my background, and my lack of python knowledge.
> Specifically lets say that I have a model with a Text field and char field.
> The char field is length 1 and says "use or do not use the text field".

A BooleanField might be better then.

> The
> char field can have Y or N values.
> So using the admin interface I wanted to override the clean method but I
> did not want to write
> if text.__len__==0 and char=='Y':
>   raise exception

"__magic_methods__" are here to support operators (or operator-like)
implementation, and except for a very few corner cases you should not
call them directly. So here you want "len(text)", not
"text.__len__()".

Also note that the parens are the "call operator", so "text.__len__"
will eval to the "__len__" method object itself (remember that in
Python everythin is an object, including classes, functions and
methods), not to the result of calling this method.

And finally, in Python, empty sequences (at least for the builtin
sequence types), empty dicts, empty strings, numeric zero (int, float
etc) and the None object all have a false value in a boolean context
(FWIW, True and False and the bool type are late additions to the
language). So the pythonic way to test for an empty string is just :

if not txt:
    print "txt is empty"

> In C/C++ you would use enum for these sort of things. So I ended with
> defining in models.py something as:
> TO_USE= (
>     ('Y', 'Yes'),
>     ('N', 'No'),
>     )
>
> class X(models.Model):
>     txt= models.CharField(db_index=True,null=True, blank=True,max_length=30)
>     use_txt=
> models.CharField(blank=False,max_length=1,default='D',choices=TO_USE)

I'd still use a BooleanField here as far as I'm concerned, but when it
comes to multiple choices, here's how I do:


class X(models.Model):
    USE_YES = 'Y'
    USE_NO = 'N'
    USE_CHOICES = (
        (USE_YES, u"Yes"),
        (USE_NO, u"No"),
        )

   use_txt = models.CharField(
       u"Use text",
       max_length=1,
       choices=USE_CHOICES,
       default=""
       )


then I can test the value using the class pseudo-constants, ie:


x = X.objects.get(pk=1)
if x.use_txt == x.USE_YES:
   pass

> and in admin.py something as
> class XForm(forms.ModelForm):
>     def clean(self):
>         cleaned_data=super(XForm, self).clean()
>         txt= cleaned_data['txt'].strip()
>         use_txt=cleaned_data['use_txt'].strip()
>
>         if txt.__len__()==0 and use_txt==TO_USE.__getitem__(0)[0]:

would be a bit better (or at least a bit less worse <g>) this way:

    if not txt and use_txt == TO_USE[0][0]:

But that's still not something I'd be happy with. My above solution
would make it a bit more readable:

    if use_txt == X.USE_YES and not txt:


>             raise forms.ValidationError('This is needed!')
>
>         return cleaned_data
>
> The part .__getitem__(0)[0] is not very readable.

Indeed. And not even consistant - if you insist on using
__magic_methods__ instead of the operators, at least go all the way:

    TO_USE.__getitem__(0).__getitem__(0)

?-)

Sorry, just kidding <g>


-- 
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 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to