Re: DB optimization docs

2010-01-15 Thread Luke Plant
I've added these docs now, or at least a good first stab at them.  
Suggestions for improvements are welcome, patches are more welcome, as 
always :-)

I backported to 1.1.X, and tried to remove any anachronisms.

Regards,

Luke

-- 
"Outside of a dog, a book is a man's best friend... inside of a 
dog, it's too dark to read."

Luke Plant || http://lukeplant.me.uk/
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Question about scope of variables in template blocks

2010-01-15 Thread Alex Rades
Hi,
I'm sorry for asking this here, but the question was raised several
time on the -users mailing list and I don't think we users have a
solution for it.

Basically, the problem is that if I call a templatetag into a block
and it fills me a variiable with the usual context[varname]=something,
then if I need that variable into another block, I have to call the
templatetag again. This for me means extra db queries, which is really
something I'm trying to avoid.

This templatetag is called in a base template which is extended by
many other templates, so I can't just change all the views to pass
something to the context, it makes no sense (WET principle?)

Even a context processor would be not good because I don't want to
call it for every page rendered in the site, even the ones not based
on that template.

I was thinking about writing a templatetag which would use the
internal context structures to put the variable in a global context,
but I'd feel too guilty doing it.

How would you solve this problem?
Thank you!
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: Question about scope of variables in template blocks

2010-01-15 Thread Jacob Kaplan-Moss
Hi Alex --

On Fri, Jan 15, 2010 at 8:41 PM, Alex Rades  wrote:
> I'm sorry for asking this here, but the question was raised several
> time on the -users mailing list and I don't think we users have a
> solution for it.

I hate to be a jerk, but django-dev isn't "second-level support" or
somesuch. Not getting a satisfactory answer on django-users doesn't
somehow qualify the question for "promotion" here.

There are a lot of other options besides django-users -- the #django
IRC channel, StackOverflow, comp.lang.python,  Please, help us
keep this list focused, and use them.

Of course, If you've got a proposal or a patch that you think would
improve things then *by all means* bring it up here.

Jacob

PS: To speak to your original question: caching. Learn to love it.
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: Logging format decision

2010-01-15 Thread Vinay Sajip
Further to my earlier post - I've put the whole branch on Launchpad:

https://code.launchpad.net/~vinay-sajip/django/logging

There's nothing much there at the moment, apart from some code as a
proof of concept. Tested with the following code tacked on at the end
of a vanilla settings.py:

import logging

def init_logging():
#Configure root to write to file
logging.basicConfig(level=logging.DEBUG, filename='logtest.log',
filemode='w', format='%(asctime)s %
(levelname)-8s %(name)-13s %(message)s')
alogger = logging.getLogger("logtest")
alogger.setLevel(logging.INFO)
logger = logging.getLogger("logtest.foo")
logger.setLevel(logging.WARNING)
logger = logging.getLogger("logtest.bar")
logger.setLevel(logging.ERROR)
#Call dummy function in django.utils.log
from django.utils.log import configure_from_dict
configure_from_dict({'version' : '0'})
alogger.info("Called configure_from_dict (just to show we can)")

def test_logging():
from random import choice
levels = (logging.DEBUG, logging.INFO, logging.WARNING,
  logging.ERROR, logging.CRITICAL)
loggers = ('', 'logtest', 'logtest.foo', 'logtest.bar')
for i in xrange(1000):
level = choice(levels)
logger = logging.getLogger(choice(loggers))
logger.log(level, "Message #%d", i + 1)


def listener(sender, *args, **kwargs):
logger = logging.getLogger("logtest")
logger.info("class_prepared listener called: %s", sender.__name__)

def pre_model_callback():
from django.db.models.signals import class_prepared
logger = logging.getLogger("logtest")
logger.info("Adding class_prepared listener ...")
class_prepared.connect(listener)

def post_model_callback():
from django.contrib.auth.models import User
logger = logging.getLogger("logtest")
try:
umsg = "%(username)s (%(first_name)s %(last_name)s)"
users = ", ".join([umsg % u.__dict__ for u in User.objects.all
()])
logger.info("ORM works: all users: %s" % users)
except:
logger.exception("Unable to get all users")

BOOTSTRAP_CALLBACKS = (
init_logging,
#test_logging,
)

PRE_MODEL_CALLBACKS = (
pre_model_callback,
)

POST_MODEL_CALLBACKS = (
post_model_callback,
)
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Fully Polymorphic Django Models: a simple implementation

2010-01-15 Thread Bert Constantin
Hello everyone!

I just uploaded a simple but mostly complete implementation of model
and queryset polymorphism onto github and bitbucket.

For enabled models, this implementation simply makes all references
to the model's objects polymorphic (be it managers/querysets or
relationship fields).

The prototype might be useful as a tool for concretely exploring the
concept of polymorphic models within the Django framework (and
perhaps might find use in real projects as well).

My impression is that fully polymorphic models and querysets
integrate very well into the Django ORM and database API. Also, with
Django's ORM and model inheritance system, all the heavy lifting
has already been done; only a rather thin layer above seems
to be required to get to a complete implementation of polymorphic
inheritance.

Below I copied the docstring of the module.
Near the top are a number of short examples that are good as a quick
overview.

The docstring can be read in a much better format here:
http://bserve.webhop.org/wiki/django_polymorphic

Suggestions and criticism are very welcome.

Kind Regards,
Bert Constantin

GitHub: http://github.com/bconstantin/django_polymorphic
Bitbucket: http://bitbucket.org/bconstantin/django_polymorphic
Tar: http://github.com/bconstantin/django_polymorphic/tarball/master

+++

Defining Polymorphic Models
===

To make models polymorphic, use PolymorphicModel instead of Django's
models.Model as the superclass of your base model. All models
inheriting from your base class will be polymorphic as well::

from polymorphic import PolymorphicModel

class ModelA(PolymorphicModel):
field1 = models.CharField(max_length=10)

class ModelB(ModelA):
field2 = models.CharField(max_length=10)

class ModelC(ModelB):
field3 = models.CharField(max_length=10)


Using Polymorphic Models


Most of Django's standard ORM functionality is available
and works as expected:

Create some objects
---

>>> ModelA.objects.create(field1='A1')
>>> ModelB.objects.create(field1='B1', field2='B2')
>>> ModelC.objects.create(field1='C1', field2='C2', field3='C3')

Query results are polymorphic
-

>>> ModelA.objects.all()
.
[ ,
  ,
   ]

Filtering for classes (equivalent to python's isinstance() ):
-

>>> ModelA.objects.instance_of(ModelB)
.
[ ,
   ]

In general, including or excluding parts of the inheritance tree::

ModelA.objects.instance_of(ModelB [, ModelC ...])
ModelA.objects.not_instance_of(ModelB [, ModelC ...])

Polymorphic filtering (for fields in derived classes)
-

For example, cherrypicking objects from multiple derived classes
anywhere in the inheritance tree, using Q objects (with the
slightly enhanced syntax: exact model name + three _ + field
name):

>>> ModelA.objects.filter(  Q( ModelB___field2 = 'B2' )  |  Q
( ModelC___field3 = 'C3' )  )
.
[ ,
   ]

Combining Querysets of different types/models
-

Querysets may now be regarded as object containers that allow the
aggregation of  different object types - very similar to python
lists (as long as the objects are accessed through the manager of
a common base class):

>>> Base.objects.instance_of(ModelX) | Base.objects.instance_of
(ModelY)
.
[ ,
   ]

Using Third Party Models (without modifying them)
-

Third party models can be used as polymorphic models without any
restrictions by simply subclassing them. E.g. using a third party
model as the root of a polymorphic inheritance tree::

from thirdparty import ThirdPartyModel

class MyThirdPartyModel(PolymorhpicModel, ThirdPartyModel):
pass# or add fields

Or instead integrating the third party model anywhere into an
existing polymorphic inheritance tree::

class MyModel(SomePolymorphicModel):
my_field = models.CharField(max_length=10)

class MyModelWithThirdParty(MyModel, ThirdPartyModel):
pass# or add fields

ManyToManyField, ForeignKey, OneToOneField
--

Relationship fields referring to polymorphic models work as
expected: like polymorphic querysets they now always return the
referred objects with the same type/class these were created and
saved as.

E.g., if in your model you define::

field1 = OneToOneField(ModelA)

then field1 may now also refer to objects of type ModelB or
ModelC.

A ManyToManyField example::

# The model holding the relation may be any kind of model,
polymorphic or not
class RelatingModel(models.Model):
many2many = 

Re: Porting Django to Python 3

2010-01-15 Thread Martin v . Löwis
> > In many cases, this is true, but there are other scenarios (certain
> > forms of exception handling, for example) where there is no syntax
> > that's valid in both versions. That's syntax, not just libraries and
> > functions. There's no way to even get a file to parse in both Python 2
> > and Python 3 in these situations.
>
> Martin's approach was single codebase where the 3.x version for execution is
> generated by 2to3, not single source for execution across 2.x and 3.x.  Thus
> I'm wondering if this difference is accounted for by 2to3?

Most certainly - that's the whole *point* of 2to3. Converting the
cases where
the syntax differs are actually the easy parts - it is very easy to
find out, by
static analysis, that Python 3 would reject a piece of code, and to
propose
a reformulation that is equivalent. That's where 2to3 shines, and thus
where
anybody adding 3.x support to a 2.x code base doesn't need to worry at
all.

When the syntax is correct in both versions, but library names
differs, 2to3
still works fairly well if it guesses correctly that the name indeed
refer to the
renamed libraries (which has some degree of uncertainty in Python).

The really difficult cases for 2to3 is where a piece of code works
unmodified
in both 2.x and 3.x, but does something significantly different. For
example,
string literals mean something different, and the result of reading
from a file
may be different (unicode vs. bytes in both cases). Fortunately,
Django
already attempts to differentiate bytes and unicode fairly well, so it
was
easy to fix the remaining spots which would break under 3.x.

Regards,
Martin

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: AnonymousUser has_perm/has_module_perms function check authentication backends

2010-01-15 Thread Anton Bessonov
No. You need row based permissions if You will limit User(!) rights. For 
example user can edit entries with FK 2. See 
http://code.djangoproject.com/wiki/RowLevelPermissions


But AnonymousUser (Guest) don't have any permissions. It's a special and 
that the guest can - it's not a permission - it's a setting.



Gert Van Gool schrieb:

Isn't the idea of row based permission that you don't need a special
model for that?

-- Gert

Mobile: +32 498725202
Web: http://gert.selentic.net

  
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: Logging format decision

2010-01-15 Thread Vinay Sajip
On Jan 15, 1:47 pm, Simon Willison  wrote:
> My biggest hangup with the logging implementation was figuring out
> exactly when the logging configuration code should actually run. The
> problem is that Django's startup execution order is poorly defined -
> stuff relating to settings is lazily evaluated the first time it's
> needed, and there's no real documented place to put code that needs to
> be executed once (the fact so many registration things end up being
> called from urls.py is a good indicator that this is a problem).
>
> This has put me off using signal handlers in my own code in the past,
> and it also came up with the logging work.
>
> I think Django needs a defined and documented execution order on
> startup. I'm not entirely clear why we've avoided this in the past -
> I've readhttp://www.b-list.org/weblog/2007/nov/05/server-startup/but
> it hasn't convinced me that a defined startup order for things like
> registration patterns, signal handlers, logging configuration is a bad
> thing.
>
> Personally, I'd like to see this happen as part of the instantiation
> of a single Django "site object" which handles all requests to the
> server. We almost do this at the moment - if you look at the code 
> inhttp://code.djangoproject.com/browser/django/trunk/django/core/handlers/
> each handler basically instantiates an object once which then has its
> get_response() method called for every incoming request. Unfortunately
> the time at which this object is instantiated seems to be pretty ad-
> hoc - how and when it happens depends on if you're running under WSGI,
> mod_python or the development server.
>
> Defining Django's execution order is a pretty big job, but it would be
> a great thing to achieve for 1.3. The obvious thing to tie it to would
> be INSTALLED_APPS - it could be as simple as having an API promise
> that the first thing Django does when it "starts" is to run through
> each application in INSTALLED_APPS looking for and importing an
> autoload.py module. I imagine we'll find that the time at which models
> are registered is critical (what if autoload.py wants to use a model
> that hasn't been loaded in to the AppCache yet?) and may need to do
> more than one pass through INSTALLED_APPS. Plenty of details to figure
> out.

You make many valid points, Simon, but at least as far as the narrower
goal of setting up logging is concerned, I had a look at this back in
October and came up with a candidate solution which worked for me. I'd
be grateful if you took a look at it and highlight any drawbacks of
the approach. The one point we know must be reached before any request
handling takes place is the reading of settings.py, so I based my
approach on that. From what I can see, the approach I've outlined is
not just suitable for setting up logging but also doing model-related
stuff such as listening for e.g. class_prepared signals etc. from the
app loading machinery.

Here's a link to the October post:

http://groups.google.com/group/django-developers/msg/90b81d9f927d0bf0

Regards,

Vinay Sajip
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: Logging format decision

2010-01-15 Thread Vinay Sajip
On Jan 15, 1:47 pm, Simon Willison  wrote:
> On Jan 14, 1:57 am, Russell Keith-Magee 
> wrote:
>
> > The other issue that I think still needs to be addressed is the
> > internal usage of logging by Django itself.
>
> My biggest hangup with the logging implementation was figuring out
> exactly when the logging configuration code should actually run. The
> problem is that Django's startup execution order is poorly defined -
> stuff relating to settings is lazily evaluated the first time it's
> needed, and there's no real documented place to put code that needs to
> be executed once (the fact so many registration things end up being
> called from urls.py is a good indicator that this is a problem).
>
> This has put me off using signal handlers in my own code in the past,
> and it also came up with the logging work.
>
> I think Django needs a defined and documented execution order on
> startup. I'm not entirely clear why we've avoided this in the past -
> I've readhttp://www.b-list.org/weblog/2007/nov/05/server-startup/but
> it hasn't convinced me that a defined startup order for things like
> registration patterns, signal handlers, logging configuration is a bad
> thing.
>
> Personally, I'd like to see this happen as part of the instantiation
> of a single Django "site object" which handles all requests to the
> server. We almost do this at the moment - if you look at the code 
> inhttp://code.djangoproject.com/browser/django/trunk/django/core/handlers/
> each handler basically instantiates an object once which then has its
> get_response() method called for every incoming request. Unfortunately
> the time at which this object is instantiated seems to be pretty ad-
> hoc - how and when it happens depends on if you're running under WSGI,
> mod_python or the development server.
>
> Defining Django's execution order is a pretty big job, but it would be
> a great thing to achieve for 1.3. The obvious thing to tie it to would
> be INSTALLED_APPS - it could be as simple as having an API promise
> that the first thing Django does when it "starts" is to run through
> each application in INSTALLED_APPS looking for and importing an
> autoload.py module. I imagine we'll find that the time at which models
> are registered is critical (what if autoload.py wants to use a model
> that hasn't been loaded in to the AppCache yet?) and may need to do
> more than one pass through INSTALLED_APPS. Plenty of details to figure
> out.

You make many valid points, Simon, but at least as far as the narrower
goal of setting up logging is concerned, I had a look at this back in
October and came up with a candidate solution which worked for me. I'd
be grateful if you took a look at it and highlight any drawbacks of
the approach. The one point we know must be reached before any request
handling takes place is the reading of settings.py, so I based my
approach on that. From what I can see, the approach I've outlined is
not just suitable for setting up logging but also doing model-related
stuff such as listening for e.g. class_prepared signals etc. from the
app loading machinery.

Regards,

Vinay Sajip
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: phone2numeric doesn't convert "Q" or "Z"

2010-01-15 Thread Andrew Gwozdziewycz
Right. Not constructing the map every time is an obvious enhancement.
My point was simply that using a regex for this particular simple task
doesn't make much sense.

On Fri, Jan 15, 2010 at 9:15 AM, Mike Axiak  wrote:
> If you really want to be fast, you can do the following, a la urllib.quote::
>
>    _phone_chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>             'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k':
> '5', 'l': '5',
>             'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r':
> '7', 's': '7',
>             't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y':
> '9', 'z': '9',
>             }
>    _phone_chars_compiled = None
>
>    def phone2number(szinput):
>        global _phone_chars_compiled
>        if _phone_chars_compiled is None:
>            _phone_chars_compiled = {}
>            for i in range(256):
>                a = chr(i)
>                _phone_chars_compiled[a] = _phone_chars.get(a, a)
>
>        return ''.join(map(_phone_chars_compiled.__getitem__, szinput))
>
> It yields a 4x speedup over your code (which constructs the map on
> every iteration?). Of course we're talking about microseconds, but I
> guess every bit counts...
>
> Cheers,
> Mike
>
> On Fri, Jan 15, 2010 at 6:41 AM, Andrew Gwozdziewycz  wrote:
>> Why use regular expressions at all for this? A timeit benchmark shows
>> a greater than 4x speedup with a rangetest in a loop over the string:
>>
>> def phone2number(str):
>>    chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>>         'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5',
>>         'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7',
>>         't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9',
>>        }
>>
>>    out = ''
>>    for n in phone:
>>        x = n.lower()
>>        o = ord(x)
>>        if o > 96 and o < 123:
>>            out += chars[x.lower()]
>>        else:
>>            out += x
>>    return out
>>
>> I know your patch was just adding back Q and Z, but there's no need
>> for a regular expression here.
>>
>> On Thu, Jan 14, 2010 at 5:33 PM, Gabriel Hurley  wrote:
>>> I've opened a ticket and submitted a patch that fixes this strange
>>> oversight: http://code.djangoproject.com/ticket/12613
>>>
>>> Thanks!
>>>    - Gabriel
>>>
>>> On Jan 14, 5:05 am, Harro  wrote:
 hmm that's indeed weird. The regex excludes those as well
 specifically.
 The Q and Z should be added or a comment should be added to the code
 explaining the reason for leaving them out.

 On Jan 14, 11:23 am, Gabriel Hurley  wrote:



 > 1. Is there a reason Django's phone2numeric method doesn't work for
 > the letters Q or Z? I realize that those two letters are the ones that
 > share four letters to a number instead of the standard three, but
 > that's no reason to leave them out. Most modern phones include the
 > full alphabet on their keys and it's silly not to let people convert
 > those two letters.

 > If there's no reason, I'd be happy to submit a patch since it's such
 > an easy fix.

 > 2. I was also wondering if there's a reason that the dictionary of
 > numbers/letters used in that function is in such a seemingly random
 > order... is there some brilliant logic behind it?

 > The source for the function I'm referring to is here:

 >http://code.djangoproject.com/browser/django/trunk/django/utils/text

 > Thanks!

 >     - Gabriel
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups 
>>> "Django developers" group.
>>> To post to this group, send email to django-develop...@googlegroups.com.
>>> To unsubscribe from this group, send email to 
>>> django-developers+unsubscr...@googlegroups.com.
>>> For more options, visit this group at 
>>> http://groups.google.com/group/django-developers?hl=en.
>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> http://www.apgwoz.com
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Django developers" group.
>> To post to this group, send email to django-develop...@googlegroups.com.
>> To unsubscribe from this group, send email to 
>> django-developers+unsubscr...@googlegroups.com.
>> For more options, visit this group at 
>> http://groups.google.com/group/django-developers?hl=en.
>>
>>
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To post to this group, send email to django-develop...@googlegroups.com.
> To unsubscribe from this group, send email to 
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/django-developers?hl=en.
>
>
>
>



-- 
http://www.apgwoz.com
-- 
You received this message because you are subscribed to 

Re: phone2numeric doesn't convert "Q" or "Z"

2010-01-15 Thread Łukasz Rekucki
Or you could use the builtin maketrans/translate pair:

import string
_phone2number_transtab = string.maketrans(string.ascii_letters,
"222333444555666888"*2)

def phone2number(szinput):
return szinput.translate(_phone2number_transtab)

2010/1/15 Mike Axiak :
> If you really want to be fast, you can do the following, a la urllib.quote::
>
>    _phone_chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>             'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k':
> '5', 'l': '5',
>             'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r':
> '7', 's': '7',
>             't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y':
> '9', 'z': '9',
>             }
>    _phone_chars_compiled = None
>
>    def phone2number(szinput):
>        global _phone_chars_compiled
>        if _phone_chars_compiled is None:
>            _phone_chars_compiled = {}
>            for i in range(256):
>                a = chr(i)
>                _phone_chars_compiled[a] = _phone_chars.get(a, a)
>
>        return ''.join(map(_phone_chars_compiled.__getitem__, szinput))
>
> It yields a 4x speedup over your code (which constructs the map on
> every iteration?). Of course we're talking about microseconds, but I
> guess every bit counts...
>
> Cheers,
> Mike
>
> On Fri, Jan 15, 2010 at 6:41 AM, Andrew Gwozdziewycz  wrote:
>> Why use regular expressions at all for this? A timeit benchmark shows
>> a greater than 4x speedup with a rangetest in a loop over the string:
>>
>> def phone2number(str):
>>    chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>>         'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5',
>>         'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7',
>>         't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9',
>>        }
>>
>>    out = ''
>>    for n in phone:
>>        x = n.lower()
>>        o = ord(x)
>>        if o > 96 and o < 123:
>>            out += chars[x.lower()]
>>        else:
>>            out += x
>>    return out
>>
>> I know your patch was just adding back Q and Z, but there's no need
>> for a regular expression here.
>>
>> On Thu, Jan 14, 2010 at 5:33 PM, Gabriel Hurley  wrote:
>>> I've opened a ticket and submitted a patch that fixes this strange
>>> oversight: http://code.djangoproject.com/ticket/12613
>>>
>>> Thanks!
>>>    - Gabriel
>>>
>>> On Jan 14, 5:05 am, Harro  wrote:
 hmm that's indeed weird. The regex excludes those as well
 specifically.
 The Q and Z should be added or a comment should be added to the code
 explaining the reason for leaving them out.

 On Jan 14, 11:23 am, Gabriel Hurley  wrote:



 > 1. Is there a reason Django's phone2numeric method doesn't work for
 > the letters Q or Z? I realize that those two letters are the ones that
 > share four letters to a number instead of the standard three, but
 > that's no reason to leave them out. Most modern phones include the
 > full alphabet on their keys and it's silly not to let people convert
 > those two letters.

 > If there's no reason, I'd be happy to submit a patch since it's such
 > an easy fix.

 > 2. I was also wondering if there's a reason that the dictionary of
 > numbers/letters used in that function is in such a seemingly random
 > order... is there some brilliant logic behind it?

 > The source for the function I'm referring to is here:

 >http://code.djangoproject.com/browser/django/trunk/django/utils/text

 > Thanks!

 >     - Gabriel
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups 
>>> "Django developers" group.
>>> To post to this group, send email to django-develop...@googlegroups.com.
>>> To unsubscribe from this group, send email to 
>>> django-developers+unsubscr...@googlegroups.com.
>>> For more options, visit this group at 
>>> http://groups.google.com/group/django-developers?hl=en.
>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> http://www.apgwoz.com
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Django developers" group.
>> To post to this group, send email to django-develop...@googlegroups.com.
>> To unsubscribe from this group, send email to 
>> django-developers+unsubscr...@googlegroups.com.
>> For more options, visit this group at 
>> http://groups.google.com/group/django-developers?hl=en.
>>
>>
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To post to this group, send email to django-develop...@googlegroups.com.
> To unsubscribe from this group, send email to 
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/django-developers?hl=en.
>
>
>
>



-- 
Łukasz Rekucki
-- 
You received 

Re: phone2numeric doesn't convert "Q" or "Z"

2010-01-15 Thread Mike Axiak
I forgot to handle upper case. Note that the following is  (~5%)
faster than calling .upper() on the input::

_phone_chars = {
'a': '2',
'b': '2',
'c': '2',
'd': '3',
'e': '3',
'f': '3',
'g': '4',
'h': '4',
'i': '4',
'j': '5',
'k': '5',
'l': '5',
'm': '6',
'n': '6',
'o': '6',
'p': '7',
'q': '7',
'r': '7',
's': '7',
't': '8',
'u': '8',
'v': '8',
'w': '9',
'x': '9',
'y': '9',
'z': '9',
}
_phone_chars_compiled = None

def phone2numeric(value):
global _phone_chars_compiled
if _phone_chars_compiled is None:
_phone_chars_compiled = {}
for i in range(256):
a = chr(i)
b = a.upper()
_phone_chars_compiled[a] = _phone_chars.get(a, a)
_phone_chars_compiled[b] = _phone_chars.get(b, b)

return ''.join(map(_phone_chars_compiled.__getitem__, value))

Of course, premature optimization is the root of all evil. There is
certainly a lot more code here, and I'm not sure phone2numeric is that
often called in applications. (As opposed to database/template
operations.) I'll leave you with a great comment on python
optimization [1].

Cheers,
Mike

1: http://www.codeirony.com/?p=9

On Fri, Jan 15, 2010 at 9:15 AM, Mike Axiak  wrote:
> If you really want to be fast, you can do the following, a la urllib.quote::
>
>    _phone_chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>             'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k':
> '5', 'l': '5',
>             'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r':
> '7', 's': '7',
>             't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y':
> '9', 'z': '9',
>             }
>    _phone_chars_compiled = None
>
>    def phone2number(szinput):
>        global _phone_chars_compiled
>        if _phone_chars_compiled is None:
>            _phone_chars_compiled = {}
>            for i in range(256):
>                a = chr(i)
>                _phone_chars_compiled[a] = _phone_chars.get(a, a)
>
>        return ''.join(map(_phone_chars_compiled.__getitem__, szinput))
>
> It yields a 4x speedup over your code (which constructs the map on
> every iteration?). Of course we're talking about microseconds, but I
> guess every bit counts...
>
> Cheers,
> Mike
>
> On Fri, Jan 15, 2010 at 6:41 AM, Andrew Gwozdziewycz  wrote:
>> Why use regular expressions at all for this? A timeit benchmark shows
>> a greater than 4x speedup with a rangetest in a loop over the string:
>>
>> def phone2number(str):
>>    chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>>         'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5',
>>         'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7',
>>         't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9',
>>        }
>>
>>    out = ''
>>    for n in phone:
>>        x = n.lower()
>>        o = ord(x)
>>        if o > 96 and o < 123:
>>            out += chars[x.lower()]
>>        else:
>>            out += x
>>    return out
>>
>> I know your patch was just adding back Q and Z, but there's no need
>> for a regular expression here.
>>
>> On Thu, Jan 14, 2010 at 5:33 PM, Gabriel Hurley  wrote:
>>> I've opened a ticket and submitted a patch that fixes this strange
>>> oversight: http://code.djangoproject.com/ticket/12613
>>>
>>> Thanks!
>>>    - Gabriel
>>>
>>> On Jan 14, 5:05 am, Harro  wrote:
 hmm that's indeed weird. The regex excludes those as well
 specifically.
 The Q and Z should be added or a comment should be added to the code
 explaining the reason for leaving them out.

 On Jan 14, 11:23 am, Gabriel Hurley  wrote:



 > 1. Is there a reason Django's phone2numeric method doesn't work for
 > the letters Q or Z? I realize that those two letters are the ones that
 > share four letters to a number instead of the standard three, but
 > that's no reason to leave them out. Most modern phones include the
 > full alphabet on their keys and it's silly not to let people convert
 > those two letters.

 > If there's no reason, I'd be happy to submit a patch since it's such
 > an easy fix.

 > 2. I was also wondering if there's a reason that the dictionary of
 > numbers/letters used in that function is in such a seemingly random
 > order... is there some brilliant logic behind it?

 > The source for the function I'm referring to is here:

 >http://code.djangoproject.com/browser/django/trunk/django/utils/text

 > Thanks!

 >     - Gabriel
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups 
>>> "Django 

Re: phone2numeric doesn't convert "Q" or "Z"

2010-01-15 Thread Mike Axiak
If you really want to be fast, you can do the following, a la urllib.quote::

_phone_chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
 'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k':
'5', 'l': '5',
 'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r':
'7', 's': '7',
 't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y':
'9', 'z': '9',
 }
_phone_chars_compiled = None

def phone2number(szinput):
global _phone_chars_compiled
if _phone_chars_compiled is None:
_phone_chars_compiled = {}
for i in range(256):
a = chr(i)
_phone_chars_compiled[a] = _phone_chars.get(a, a)

return ''.join(map(_phone_chars_compiled.__getitem__, szinput))

It yields a 4x speedup over your code (which constructs the map on
every iteration?). Of course we're talking about microseconds, but I
guess every bit counts...

Cheers,
Mike

On Fri, Jan 15, 2010 at 6:41 AM, Andrew Gwozdziewycz  wrote:
> Why use regular expressions at all for this? A timeit benchmark shows
> a greater than 4x speedup with a rangetest in a loop over the string:
>
> def phone2number(str):
>    chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
>         'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5',
>         'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7',
>         't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9',
>        }
>
>    out = ''
>    for n in phone:
>        x = n.lower()
>        o = ord(x)
>        if o > 96 and o < 123:
>            out += chars[x.lower()]
>        else:
>            out += x
>    return out
>
> I know your patch was just adding back Q and Z, but there's no need
> for a regular expression here.
>
> On Thu, Jan 14, 2010 at 5:33 PM, Gabriel Hurley  wrote:
>> I've opened a ticket and submitted a patch that fixes this strange
>> oversight: http://code.djangoproject.com/ticket/12613
>>
>> Thanks!
>>    - Gabriel
>>
>> On Jan 14, 5:05 am, Harro  wrote:
>>> hmm that's indeed weird. The regex excludes those as well
>>> specifically.
>>> The Q and Z should be added or a comment should be added to the code
>>> explaining the reason for leaving them out.
>>>
>>> On Jan 14, 11:23 am, Gabriel Hurley  wrote:
>>>
>>>
>>>
>>> > 1. Is there a reason Django's phone2numeric method doesn't work for
>>> > the letters Q or Z? I realize that those two letters are the ones that
>>> > share four letters to a number instead of the standard three, but
>>> > that's no reason to leave them out. Most modern phones include the
>>> > full alphabet on their keys and it's silly not to let people convert
>>> > those two letters.
>>>
>>> > If there's no reason, I'd be happy to submit a patch since it's such
>>> > an easy fix.
>>>
>>> > 2. I was also wondering if there's a reason that the dictionary of
>>> > numbers/letters used in that function is in such a seemingly random
>>> > order... is there some brilliant logic behind it?
>>>
>>> > The source for the function I'm referring to is here:
>>>
>>> >http://code.djangoproject.com/browser/django/trunk/django/utils/text
>>>
>>> > Thanks!
>>>
>>> >     - Gabriel
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "Django developers" group.
>> To post to this group, send email to django-develop...@googlegroups.com.
>> To unsubscribe from this group, send email to 
>> django-developers+unsubscr...@googlegroups.com.
>> For more options, visit this group at 
>> http://groups.google.com/group/django-developers?hl=en.
>>
>>
>>
>>
>
>
>
> --
> http://www.apgwoz.com
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To post to this group, send email to django-develop...@googlegroups.com.
> To unsubscribe from this group, send email to 
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/django-developers?hl=en.
>
>
>
>
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: Logging format decision

2010-01-15 Thread Simon Willison
On Jan 14, 1:57 am, Russell Keith-Magee 
wrote:
> The other issue that I think still needs to be addressed is the
> internal usage of logging by Django itself.

My biggest hangup with the logging implementation was figuring out
exactly when the logging configuration code should actually run. The
problem is that Django's startup execution order is poorly defined -
stuff relating to settings is lazily evaluated the first time it's
needed, and there's no real documented place to put code that needs to
be executed once (the fact so many registration things end up being
called from urls.py is a good indicator that this is a problem).

This has put me off using signal handlers in my own code in the past,
and it also came up with the logging work.

I think Django needs a defined and documented execution order on
startup. I'm not entirely clear why we've avoided this in the past -
I've read http://www.b-list.org/weblog/2007/nov/05/server-startup/ but
it hasn't convinced me that a defined startup order for things like
registration patterns, signal handlers, logging configuration is a bad
thing.

Personally, I'd like to see this happen as part of the instantiation
of a single Django "site object" which handles all requests to the
server. We almost do this at the moment - if you look at the code in
http://code.djangoproject.com/browser/django/trunk/django/core/handlers/
each handler basically instantiates an object once which then has its
get_response() method called for every incoming request. Unfortunately
the time at which this object is instantiated seems to be pretty ad-
hoc - how and when it happens depends on if you're running under WSGI,
mod_python or the development server.

Defining Django's execution order is a pretty big job, but it would be
a great thing to achieve for 1.3. The obvious thing to tie it to would
be INSTALLED_APPS - it could be as simple as having an API promise
that the first thing Django does when it "starts" is to run through
each application in INSTALLED_APPS looking for and importing an
autoload.py module. I imagine we'll find that the time at which models
are registered is critical (what if autoload.py wants to use a model
that hasn't been loaded in to the AppCache yet?) and may need to do
more than one pass through INSTALLED_APPS. Plenty of details to figure
out.

Cheers,

Simon
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: AnonymousUser has_perm/has_module_perms function check authentication backends

2010-01-15 Thread Gert Van Gool
Isn't the idea of row based permission that you don't need a special
model for that?

-- Gert

Mobile: +32 498725202
Web: http://gert.selentic.net



On Fri, Jan 15, 2010 at 13:55, Anton Bessonov  wrote:
> Hello,
>
> It's a false place. All what you need - one Model for Settings.
>
> if SettingsModel.objects.get(code='guest_can_comment'):
>  can_post
> else:
>  cant_post
>
> You can wrap this in one decorator function.
>
> Harro schrieb:
>>
>> Because the authentication backend now allows for role based
>> permissions you might have a blog post which anonymous users are
>> allowed to comment on (create_comment) and another they can't.
>>
>> Now you would have to have a guest_can_comment flag or something on
>> the blog post and check that before displaying the form.
>> Instead I want to use the permission system to see if the anonymous
>> user has create_comment permission on that specific blog item.
>>
>> so that's why I think this would be a good addition.
>>
>> It would also allow for temporary shutting down of certain publicly
>> accessible items by simply removing/disabling the permissions for
>> guest users.
>>
>>
>>
>> On Jan 14, 3:17 pm, Juan Pablo Scaletti 
>> wrote:
>>
>>>
>>> If an AnonymousUser can do something then everybody can do that as well.
>>> So why a regular unprotected view can't do the job?
>>>
>>>
>>>
>>>
>>>
>>> On Thu, Jan 14, 2010 at 8:13 AM, Harro  wrote:
>>>

 I was having a look at the new 1.2 row level permission support that
 got added and ran into the problem that the AnonymousUser does not
 call the authentication backend functions.
      The default backend doesn't need this, but with a custom backend I
 might want to implement Guest permissions.
      I think it will make the permission system even more powerful !
      What do you guys think?
      Ticket:http://code.djangoproject.com/ticket/12557
      --
 You received this message because you are subscribed to the Google
 Groups
 "Django developers" group.
 To post to this group, send email to django-develop...@googlegroups.com.
 To unsubscribe from this group, send email to

 django-developers+unsubscr...@googlegroups.com
 .
 For more options, visit this group at
 http://groups.google.com/group/django-developers?hl=en.

>>>
>>> --
>>>
>>> Juan Pablo Scaletti
>>>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-develop...@googlegroups.com.
> To unsubscribe from this group, send email to
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-developers?hl=en.
>
>
>
>
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: AnonymousUser has_perm/has_module_perms function check authentication backends

2010-01-15 Thread Anton Bessonov

Hello,

It's a false place. All what you need - one Model for Settings.

if SettingsModel.objects.get(code='guest_can_comment'):
 can_post
else:
 cant_post

You can wrap this in one decorator function.

Harro schrieb:

Because the authentication backend now allows for role based
permissions you might have a blog post which anonymous users are
allowed to comment on (create_comment) and another they can't.

Now you would have to have a guest_can_comment flag or something on
the blog post and check that before displaying the form.
Instead I want to use the permission system to see if the anonymous
user has create_comment permission on that specific blog item.

so that's why I think this would be a good addition.

It would also allow for temporary shutting down of certain publicly
accessible items by simply removing/disabling the permissions for
guest users.



On Jan 14, 3:17 pm, Juan Pablo Scaletti 
wrote:
  

If an AnonymousUser can do something then everybody can do that as well.
So why a regular unprotected view can't do the job?





On Thu, Jan 14, 2010 at 8:13 AM, Harro  wrote:


I was having a look at the new 1.2 row level permission support that
got added and ran into the problem that the AnonymousUser does not
call the authentication backend functions.
  
The default backend doesn't need this, but with a custom backend I

might want to implement Guest permissions.
  
I think it will make the permission system even more powerful !
  
What do you guys think?
  
Ticket:http://code.djangoproject.com/ticket/12557
  
--

You received this message because you are subscribed to the Google Groups
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to
django-developers+unsubscr...@googlegroups.com
.
For more options, visit this group at
http://groups.google.com/group/django-developers?hl=en.
  

--

Juan Pablo Scaletti



-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: Speeding up test running

2010-01-15 Thread Vitaly Babiy
That could also work, another problem is that many times when I am debugging
using tests I will use something like pbd. In this case we will always need
a way to fall back to the single thread mode.

On Jan 15, 2010 2:38 AM, "Russell Keith-Magee" 
wrote:

On Fri, Jan 15, 2010 at 9:59 AM, Vitaly Babiy  wrote: >
I have also been thinkin...
The other way to skin this particular cat is to have multiple test
databases, one for each thread. This approach would require a lot more
modifications to the existing test framework (to set up and allocate
individual tests/test cases to each database), but it would guarantee
that threads didn't end up with contention or corruption over a single
database.

Yours,
Russ Magee %-)

--
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to
django-developers+unsubscr...@googlegroups.com
.
For more options, visit this group at
http://groups.google.com/group/django-developers?hl=en.
-- 

You received this message because you are subscribed to the Google Groups "Django developers" group.

To post to this group, send email to django-develop...@googlegroups.com.

To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.



Re: AnonymousUser has_perm/has_module_perms function check authentication backends

2010-01-15 Thread Harro
Because the authentication backend now allows for role based
permissions you might have a blog post which anonymous users are
allowed to comment on (create_comment) and another they can't.

Now you would have to have a guest_can_comment flag or something on
the blog post and check that before displaying the form.
Instead I want to use the permission system to see if the anonymous
user has create_comment permission on that specific blog item.

so that's why I think this would be a good addition.

It would also allow for temporary shutting down of certain publicly
accessible items by simply removing/disabling the permissions for
guest users.



On Jan 14, 3:17 pm, Juan Pablo Scaletti 
wrote:
> If an AnonymousUser can do something then everybody can do that as well.
> So why a regular unprotected view can't do the job?
>
>
>
>
>
> On Thu, Jan 14, 2010 at 8:13 AM, Harro  wrote:
> > I was having a look at the new 1.2 row level permission support that
> > got added and ran into the problem that the AnonymousUser does not
> > call the authentication backend functions.
>
> > The default backend doesn't need this, but with a custom backend I
> > might want to implement Guest permissions.
>
> > I think it will make the permission system even more powerful !
>
> > What do you guys think?
>
> > Ticket:http://code.djangoproject.com/ticket/12557
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Django developers" group.
> > To post to this group, send email to django-develop...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > django-developers+unsubscr...@googlegroups.com > i...@googlegroups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/django-developers?hl=en.
>
> --
>
> Juan Pablo Scaletti
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.




Re: phone2numeric doesn't convert "Q" or "Z"

2010-01-15 Thread Andrew Gwozdziewycz
Why use regular expressions at all for this? A timeit benchmark shows
a greater than 4x speedup with a rangetest in a loop over the string:

def phone2number(str):
chars = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3',
 'f': '3', 'g': '4', 'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5',
 'm': '6', 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7',
 't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9',
}

out = ''
for n in phone:
x = n.lower()
o = ord(x)
if o > 96 and o < 123:
out += chars[x.lower()]
else:
out += x
return out

I know your patch was just adding back Q and Z, but there's no need
for a regular expression here.

On Thu, Jan 14, 2010 at 5:33 PM, Gabriel Hurley  wrote:
> I've opened a ticket and submitted a patch that fixes this strange
> oversight: http://code.djangoproject.com/ticket/12613
>
> Thanks!
>    - Gabriel
>
> On Jan 14, 5:05 am, Harro  wrote:
>> hmm that's indeed weird. The regex excludes those as well
>> specifically.
>> The Q and Z should be added or a comment should be added to the code
>> explaining the reason for leaving them out.
>>
>> On Jan 14, 11:23 am, Gabriel Hurley  wrote:
>>
>>
>>
>> > 1. Is there a reason Django's phone2numeric method doesn't work for
>> > the letters Q or Z? I realize that those two letters are the ones that
>> > share four letters to a number instead of the standard three, but
>> > that's no reason to leave them out. Most modern phones include the
>> > full alphabet on their keys and it's silly not to let people convert
>> > those two letters.
>>
>> > If there's no reason, I'd be happy to submit a patch since it's such
>> > an easy fix.
>>
>> > 2. I was also wondering if there's a reason that the dictionary of
>> > numbers/letters used in that function is in such a seemingly random
>> > order... is there some brilliant logic behind it?
>>
>> > The source for the function I'm referring to is here:
>>
>> >http://code.djangoproject.com/browser/django/trunk/django/utils/text
>>
>> > Thanks!
>>
>> >     - Gabriel
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To post to this group, send email to django-develop...@googlegroups.com.
> To unsubscribe from this group, send email to 
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/django-developers?hl=en.
>
>
>
>



-- 
http://www.apgwoz.com
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.