On Sat, Jul 18, 2009 at 11:08 AM, Beetle B.<anli...@gmail.com> wrote:
>
> Russell Keith-Magee wrote:
>> > 1. In the Python code, how can I access various Meta properties of a
>> > model (e.g. verbose_name, etc). At the moment, I do it via
>> > model._meta.verbose_name, but I always get chills down my spine when I
>> > access properties beginning with a single underscore. Is there a
>> > "proper" way?
>>
>> Yes - you pass the data you want in the context as a normal context variable.
>
> I must have been unclear: The two questions are unrelated. I want to
> know how to access the verbose_name for a model within the Python
> code, not the template.
>
> I have a function that takes in a model, and I want to get that
> model's verbose_name (or plural, or some other Meta property). Is
> there a way to do this other than model._meta.verbose_name?

My apologies - I jumped to conclusions given the overlap with your
second question.

No - there is no other way to get access to verbose_name, et al; the
_meta object is the proper way.

While the desire to avoid underscored attributes is a sound practice
to live by, using single underscore attributes, under well advised
conditions, shouldn't make you excessively nervous. The single
underscore prefix in Python is usually used to refer to an internal
property, or something that isn't really for general public access.
The underscore is supposed to give you pause for thought before you
use it - but not act as a preventative measure.

This is a fairly good description of the way you should treat _meta.
The contents of _meta aren't attributes that you should need to use as
part of the basic interface to your model (i.e., day-to-day CRUD type
operations). However, if you're starting to get introspective or do
some sort of generic programming around models, _meta is a mine of
useful descriptions of the internal composition of a model. Since
you're operating at the introspective level, you are by definition
dealing with internals, so hitting an underscored attribute that is
part of a well known and understood interface shouldn't be cause for
excessive concern.

There is also a very practical reason why _meta has an underscore:
having an underscore is one way to guarantee that there is no
accidental overlap with user-space attributes on a model.

>> > 2. Can someone explain the rationale behind not allowing access to
>> > properties of objects that begin with double underscores in the
>> > template? It worked in 1.02, but with SVN I can't access anything like
>> > object.__class__. I'm merely curious as to why this was restricted. In
>> > one or two cases, life was easier for me when I could do it.
>>
>> To the best of my knowledge, you have _never_ been able to access
>> 'protected and private' attributes(i.e., attributes starting with _)
>> in a template. Are you certain you were able to do this in the past?
>
> Yes. In fact, I only discovered that this was a problem when I
> switched to the subversion from 1.02 recently and had the site fail to
> work. It has been working fine on Webfaction's 1.02 for more than a
> month with me accessing a protected variable (double underscore, I
> believe).

Ok - first off - it's a minor nitpick, but the version number is
1.0.2, not 1.02.

> Hmm...Tried it for another object, and it isn't working as well with
> 1.02. I'm 100% sure it worked for something else I was doing - but I
> don't want to go through the trouble of duplicating it because I
> changed quite a bit of the system to get it working with subversion
> and it's probably not worth the bother. Probably an obscure bug.
>
>> If this is true, it would be a major backwards incompatibility, and
>> one that we will need to fix. However, I'm not aware of any changes
>> that have been made to the template system since v1.0 was released -
>> certainly none that would make this change.
>
> Oh what the heck. Looked through my logs and managed to duplicate:
>
> You're right, stuff like {{ object.__str__ }} doesn't work in either.
> However, in 1.02, the following works:
>
> {% ifequal object.__str__  some_string %}
> <p>Look ma! It works!
> {% endifequal %}

Ok - this is what had me confused. I was fairly certain that simple
attribute lookup wouldn't allow underscores. This was a defect in the
{% ifequal %} tag. Interestingly, if you repeat your experiment with
{% if obj.__str__ %}, rather than {% ifequal %}, you will find that
you get the TemplateSyntaxError under v1.0 and v1.0.2.

> whereas I get an exception in subversion. I don't know if that's just
> for ifequal or whether it'll occur with {% if %} and others, as well.
>
> (And I don't recall whether the match actually worked or not - but
> that's another story).
>
> Since it fails under SVN, I'm assuming it was caught and fixed. I
> haven't looked at the Incompatibility list to see if it's there.

In this case, it's not a backwards incompatibilty -  the old behaviour
was a bug, and it has now been fixed. The {% if %} tag demonstrates
that this wasn't intended behaviour.

The development branch of Django has seen a few refactorings in the
template tag code aimed at rationalizing the use of certain internal
functions - such as the function for performing attribute lookup.
Evidently {% ifequal %} is one of the tags that has particularly
benefitted from this refactor.

> Anyway, though, what's the rationale for not allowing double
> underscored properties? I know single underscores are considered poor
> practice, but I don't recall that accessing the double underscore
> properties as being discouraged. After all, people do it all the time
> in Python, and I'm sure Django's source makes heavy use of it...

The way you phrase the question leads directly to the answer. Using
underscores is common in  _Python_. Django's template language is
_not_ Python. One of the core design decisions of the template
language is to _avoid_ making it a programming language. The extent to
which Django's template language imitates Python is limited to the
extent to which Python imitates natural language.

Also - neither single nor double underscores are "discouraged" in
Python generally - they just serve as guidance for API usage. A _very_
rough analogy is that a single underscore indicates "protected", and a
double underscore indicates "private", although this analogy doesn't
apply in the same way that it applies to languages like Java or C++.
Names that follow the __*__ pattern are another case again; they're
generally the internal implementations for other features. While there
is nothing in Python that prevents you from invoking any protected,
private or internal methods directly, you would well advised to
consider their use carefully, and the more underscores involved, the
more consideration should be given.

When you translate this principle to the template language - Django's
template language tries to enforce a strict separation of concerns.
There should be no programming logic in the template. By extension, a
template shouldn't need to delve into the protected internals of an
implementation. If some property that is protected or private in the
implementation needs to be rendered, it should be exposed directly
into the template context, so, from the point of view of the Template,
it is just data than needs to be displayed.

Yours,
Russ Magee %-)

--~--~---------~--~----~------------~-------~--~----~
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