Re: Template inheritance and {% include %} tags

2008-09-18 Thread Simon Willison

On Sep 18, 6:39 pm, Michael  Elsdörfer <[EMAIL PROTECTED]> wrote:
> I remember this coming up on django-users and IRC once or twice, and
> never thought too much about it, but currently, template inheritance
> and includes don't work together at all:
>
> * Blocks included in a parent template cannot be overwritten in a
> child template.
> * Blocks from an include in a child template cannot overwrite blocks
> in a parent template.

I've got a workaround for that which works pretty well:

http://code.djangoproject.com/wiki/ExtendingTemplates

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: RFC: django.template refactoring (#7806)

2008-09-16 Thread Simon Willison

On Sep 16, 7:36 pm, Johannes Dollinger
<[EMAIL PROTECTED]> wrote:
> @register.tag
> @uses_token_stream
> def mytag(parser, bits):
>      expr = bits.parse_expression(required=True)
>      return MyNode(expr)
>
> `uses_token_stream` replaces the Token argument to the parser  
> function with a TokenStream object.

I'm completely in favour of some refactoring in django.template, but
I'm not at all keen on that decorator syntax. Nested decorators get
ugly quickly in my opinion, especially considering our need to keep
supporting Python 2.3 syntax.

Would @register.tag(token_stream=True) work instead, or am I missing
something?

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: Enhanced simple-tag decorator #1105

2008-09-16 Thread Simon Willison

On Sep 16, 1:03 pm, Julien Phalip <[EMAIL PROTECTED]> wrote:
> This is a call to review ticket #1105. The proposed patch is fully
> functional, backwards-compatible and contains tests and 
> documentation.http://code.djangoproject.com/ticket/1105
>
> Currently it is not possible to access the context from within a
> simple_tag, and there is no "simple" way to create block tags. Both of
> these tasks imply using some boilerplate code to parse the tokens,
> manage variables, etc.

+1, I love it. I've been using this in my own projects for ages.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: user-friendly API for multi-database support

2008-09-12 Thread Simon Willison

On Sep 12, 7:45 pm, Brent Hagany <[EMAIL PROTECTED]> wrote:
> As far as I can tell, the argument about being portable is a good one,
> and if that ends up being the reason this doesn't get in right away,
> then I can't complain.  However, the part about the single server
> making this more specialized, and the part about performance are non
> sequiturs.  The vast majority of web applications run with a single
> database server; I don't see how that can be called specialized.  And,
> the reasons for wanting to do cross-database joins (from my POV) have
> nothing to do with performance, so I don't really understand why it's
> relevant to this part of the proposal.

To be honest, the main reason I proposed avoiding this problem is it
sounded like it might be difficult so I was trying to constrain the
scope a bit, plus I don't know if the ability to do cross-database
joins exists outside of MySQL. From a quick search, it looks like
PostgreSQL doesn't support it: http://www.postgresql.org/docs/faqs.FAQ.html
but Oracle does: http://www.remote-dba.cc/oracle_tips_sql_joins.htm

Anyway, it turns out Django supports cross-database joins in MySQL
already! It's a bit of a hack, but it works right now, with no
modifications needed to Django at all.

The only difference between a cross-database join and a regular join
in MySQL is that in cross-database joins the database name is included
in each table reference:

SELECT database1.table1.column1, database2.table2.column2
FROM database1.table1 ...

So, my first attempt was to add the database name to the db_table
property in class Meta:

class Topic(models.Model):
name = models.CharField(max_length = 100)
slug = models.SlugField()

class Meta:
db_table = "other_database.review_topic"

def __unicode__(self):
return self.name

That didn't work, because Django adds escaping quotes around each
table reference. Here's the generated SQL:

SELECT
   `other_database. review_topic `.`id`,
   `other_database.review_topic`.`name`,
   `other_database.review_topic`.`slug`
FROM `other_database.review_topic`

You can probably guess where this is going: if you include the
backticks around the . in your db_table setting everything works just
fine!

class Meta:
db_table = "other_database`.`review_topic"

Regular selects, joins and everything else appear to Just Work out of
the box. It turns out we don't have to do anything special to enable
cross-database joins / models in different databases accessible
through the same logical connection on MySQL, which is pretty cool.
It's a shame the syntax is hacky though. One slight improvement would
be to allow the db_table property to optionally include its own table
quoting and only add backticks if that string didn't have them
already. That way you could do the following, which is slightly less
hacky:

class Meta:
db_table = "`other_database`.`review_topic`"

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: user-friendly API for multi-database support

2008-09-12 Thread Simon Willison

On Sep 12, 10:46 pm, TP <[EMAIL PROTECTED]> wrote:
> > This means an ORM object should have a
> > special property on it recording which database connection it was
> > loaded from. It also presumes we won't ever want to support the case
>
> I apologize for my ignorance as to how django DB connections work, but
> will this lead to thread safety issues if one thread loads an object
> and passes it into another thread? Or is the underlying Django
> connection thread safe?
>
> Also, what if the connection has closed for whatever reason since the
> object was loaded (due to DB connection timeout, DB restart, etc)?

Sorry, that was a clumsy explanation on my part. I didn't mean store
the actual connection object; I meant store information about which
database was used. How this is stored (DatabaseWrapper instance, DSN
string, connection alias) is up to the implementation, but it should
certainly take the factors you describe in to account.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: user-friendly API for multi-database support

2008-09-12 Thread Simon Willison

On Sep 12, 5:11 pm, mengel <[EMAIL PROTECTED]> wrote:
> > obj = Article.objects.using('master').get(pk = 4)
> > obj.name = 'Hello'
> > obj.save(using = 'master')
>
> Shouldn't the object remember the database used to fetch it, and
> save() should save it back there?    Then you would only have to
> specify it like that if you want to fetch it from one database and
> save it in another explicitly...

That sounds smart to me. There are cases where you want to select from
one database and then save to another (moving data between different
database servers, re-sharding data for whatever reason) but the common
case will be as you describe. This means an ORM object should have a
special property on it recording which database connection it was
loaded from. It also presumes we won't ever want to support the case
where a model consists of properties loaded from more than one
database (title and date from 'metadata', abstract and content from
'content') - I think this is a perfectly reasonable limitation; if you
want to do something like that you can write your own class that
composes two ORM models behind the scenes.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: user-friendly API for multi-database support

2008-09-10 Thread Simon Willison

On Sep 10, 10:55 pm, ab <[EMAIL PROTECTED]> wrote:
> For the api to accept a DSN, alias, or connection anywhere would add
> similar code in multiple places. I propose that the aliases are mapped
> into django.db.connections. For your example, you could use
> django.db.connections.archive.

I'm keen on the DSN/alias/connection trichotomy for the following
reasons:

1. It's more pleasant to hand around short strings than long object
references.
2. Allowing a DSN to be provided means you don't have to pre-define
every single one of your databases in your settings.py. WordPress.com
is an example of why you might not want to do this: they have
literally thousands of databases each hosting a bundle of blogs -
their system simply wouldn't work if every database connection had to
be pre-defined.
3. Allowing an actual connection object to be handed around means you
can take full advantage of Python's duck-typing to do pretty much
anything you like.

> Counter-proposal:
> A *project-global* get_connection function, maybe in a location
> specified by settings.

That seems like a smart compromise. It allows for over-riding existing
applications and, like you said, keeps all of the tricky connection
logic in a single place.

I'm still interested in the simple case of allowing individual models
to live on different databases, but one way of tackling that could be
the following:

# settings.py
DATABASE_PICKER = 'django.contrib.multidb.per_model_database'

# models.py
class Article(models.Model):
...
class Meta:
using = 'archive'

The per_model_database connection picker would use model._meta.using
to decide which connection to return.

> Input: the queryset, at least, and probably whatever else you'll
> likely want to use: the model class, tables joined with,
> fields_accessed?, etc.
> Output: a connection object

I still think the input should be a Query rather than a QuerySet
(since a QuerySet isn't available in the case of insert() or
update()). The query object should provide enough information to make
a decision in most (all?) cases, and you can always use query.model to
get back to the original model definition. It might be useful for the
ORM to annotate query with the corresponding queryset, if one is in
use - such at you can access it as query.queryset from inside the
connection picker.

This is a really enlightening thread (for me at least) - I'm going to
collect together the various requirements that have been highlighted
on a wiki page, probably tomorrow morning.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: user-friendly API for multi-database support

2008-09-10 Thread Simon Willison

On Sep 10, 10:44 pm, Ivan Sagalaev <[EMAIL PROTECTED]> wrote:
> Well... To be sure save() should always go to master because on slaves
> you just don't have permissions to save anything. So a parameter to
> save() is redundant.

It's redundant in the case of a single master, but there are other
situations when you might want full control over where a save() ends
up going (when you have more than one master for example, or in a
situation where you are loading data from one database and saving it
to another as part of an import/export routine).

> To be honest, I like the approach that I've implemented in my db backend
> for this: using HTTP semantics with the ability to force mater or slave
> when you need it. However it works with an implicit state which is not a
> clean approach compared to a functional one with explicit passing of
> connections.

I had your POST v.s. GET method in mind when I was thinking about the
get_connection method - one of the potential things you could do in
that method is look at a thread local that was set to the request
method when the last request came in. This is a bit too much of a hack
to support in Django core but there's nothing to stop end-users using
thread locals in that way if they want HTTP-based master/slave
selection.

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



Re: Proposal: user-friendly API for multi-database support

2008-09-10 Thread Simon Willison

On Sep 10, 10:24 pm, "Mike Malone" <[EMAIL PROTECTED]> wrote:
> At Pownce, for example, we stick users to the master database for some
> period of time (a couple of seconds, usually) after they post a new note.
> The problem here (as Malcolm pointed out) is that related managers use the
> default manager for the related field. So if I ask for a User's Notes, the
> default Note manager is used. That manager is, presumably, where the
> decision is going to be made as to whether the slave or the master should be
> queried. But the Note manager has no way of knowing whether the User is
> stuck to the master -- it doesn't even know that there's a User associated
> with the query...

That's really interesting. I wonder if that invalidates the whole
approach I proposed, or merely means it needs some refining?

> Simon, from your first email it seems you're suggesting that the Manager
> call Query.as_sql() and then parse the resulting SQL string?

Not at all - I'm suggesting the manager pokes around at the query
object itself (what type of query is it, which tables does it touch
etc). I mentioned as_sql as a throw-away remark; I certainly wouldn't
want to suggest implementing connection selection logic in that way.

> IMO, the right place for a decision like "should this User's notes come from
> the master, or the slave?" is on the User model (or maybe User manager),
> not in the Note manager.

It's possible that the Note manager simply won't have enough
information to make that decision - in which case I'd suggest that
solving it is up to the developer. They might chose to use the
'using()' method to force a query through notes to go to the slave,
for example.

> The same problem comes up with sharding. Suppose, for example, Pownce
> started sharding by User and putting each User's Notes on the same server
> the User is on. We should be able to call User.notes.all() and get that
> User's notes, but the Note manager can't easily tell what server it should
> be querying, since it doesn't know about the User. Again, you could start
> poking at the internals of Query and try to figure out what's going on, but
> that doesn't seem like a particularly elegant solution...

Again, my assumption is that in that case it's up to the developer to
ensure queries go to the right place - maybe by adding their own
"get_notes" method to their user object that automatically queries the
correct shard (with the using() method).

I'm not convinced that this stuff can be made invisible to the
developer - if you're sharding things you're in pretty deep, and you
probably want to maintain full control over where your queries are
going.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: user-friendly API for multi-database support

2008-09-10 Thread Simon Willison

On Sep 10, 10:15 pm, Ivan Sagalaev <[EMAIL PROTECTED]> wrote:
> Simon Willison wrote:
> > * Simple master-slave replication: SELECT queries are distributed
> >   between slaves, while UPDATE and DELETE statements are sent to
> >   the master.
>
> It won't work on a statement-level. If you have a transaction and do an
> UPDATE and then a SELECT then the latter won't see results of the former
> because it will look into another connection (and another database).
>
> I strongly believe that choosing between a master and a slave is the
> decision that should be made on business logic level, not at model level.

Good point. That also highlights an omission in my original brain-dump
- having a "uses" method on a QuerySet isn't enough, you also need a
way of over-riding the database connection used by a call to
model.save(). Again, I'd propose the same terminology again as a
keyword argument.

If you wanted to control which master/slave connection was used from
your business logic, you'd do something like this:

obj = Article.objects.using('master').get(pk = 4)
obj.name = 'Hello'
obj.save(using = 'master')

Ivan: how does that look?



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



Solving registration once and for all?

2008-09-10 Thread Simon Willison

On Sep 10, 9:18 pm, Malcolm Tredinnick <[EMAIL PROTECTED]>
wrote:
> Oh, please, no! Registration is a very fragile process. It simply
> doesn't work very well. It's a bit disappointing that it's the way we
> have to do things that way in places in Django and if we can avoid it
> elsewhere that'd be nice.

I was hoping we could get a discussion going about this at DjangoCon.
Registration is a pattern that comes up /all the time/ in Django:

* Registering models with the admin
* Registering models with databrowse
* Registering template tags
* Registering custom management commands

It's also present in popular party apps:

* django-tagging and django-mptt both register models (though both
feel like they should really be some kind of mixin)

We'll also need it in the near future for a couple of in-development
features:

* Registering custom panels with the Django debugging toolbar
* Registering new benchmarks with the metronome profiling tool
* Registering get_connection overrides in the above multi-db proposal

Finally, we've been needing to solve it for projects at work: we have
a CMS that exposes a concept of "custom rows" which can be provided by
applications and dropped in to various places around the site. Guess
what: the rows need to be registered!

There MUST be a good way of doing this. zope.interface? setuptools
entry points? We really, really need to solve this for Django. If we
had a single, supported and documented way of registering things it
would open up a huge amount of potential for plugin-style extension
points and give us a proper solution to a problem we are solving in a
bunch of different ways at the moment.

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



Re: Proposal: {% doctype %} and {% field %} tag for outputting form widgets as HTML or XHTML

2008-09-10 Thread Simon Willison

On Sep 10, 5:29 pm, "Rob Hudson" <[EMAIL PROTECTED]> wrote:
> To avoid adding yet another setting (unless it's warranted here) can
> the setting of a doctype in a template tag set a value in
> django.conf.settings that django.forms can then check (with a
> reasonable default)?
>
> I recall seeing a patch that adds a new setting and updates (at the
> time) django.newforms with some if/else logic based on the setting to
> the various widgets' render methods.  I can't seem to find it now.
>
> I'm just trying to point out that for Django to output a string that
> then later gets "fixed" smells funny to me (ask Malcolm likes to say).

I completely agree, but I don't think the answer is to use a global
variable to influence django.forms. My plan for integration in to
Django proper was to modify Django's widget.render method to take an
optional as_xhtml=True/False argument. The {% form %} tag would then
set that argument based on context._doctype.

I would also modify Context to have an is_xhtml() method which does
the "self._doctype in xhtml_doctypes" check.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: user-friendly API for multi-database support

2008-09-10 Thread Simon Willison

On Sep 10, 7:17 pm, Malcolm Tredinnick <[EMAIL PROTECTED]>
wrote:
> Also, as a general thing here, did you go back and read the various
> discussions we had about API when the multi-db Summer of Code project
> was running? If not, that would be worth doing and incorporating, since
> we debated a few alternatives for things back then which will still be
> somewhat relevant

I'm pretty sure I did at the time :) The above is a brain dump based
on months of quiet chewing followed by a burst of inspiration from
your Django talk. Are there any threads in particular that you think
are worth revisiting?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Proposal: user-friendly API for multi-database support

2008-09-10 Thread Simon Willison

For those who weren't at DjangoCon, here's the state of play with
regards to multi-db support: Django actually supports multiple
database connections right now: the Query class (in django/db/models/
sql/query.py) accepts a connection argument to its constructor, and
the QuerySet class (django/db/models/query.py) can be passed an
optional Query instance - if you don't pass it one, it will create a
Query that uses the default django.db.connection.

As a result, if you want to talk to a different connection you can do
it right now using a custom manager:

class MyManager(Manager):

def get_query_set(self):
query = sql.Query(self.model, my_custom_db_connection)
return QuerySet(self.model, query)

As Malcolm described it, he's provided the plumbing, now we need to
provide the porcelain in the form of a powerful, user-friendly API to
this stuff. Here's my first attempt at an API design.

Requirements


There are a number of important use-cases for multi-db support:

* Simple master-slave replication: SELECT queries are distributed
  between slaves, while UPDATE and DELETE statements are sent to
  the master.
* Different Django applications live on different databases, e.g.
  a forum on one database while blog lives on another.
* Moving data between different databases - it would be useful if
  you could do this using the ORM to help paper over the
  differences in SQL syntax.
* Sharding: data in a single Django model is distributed across
  multiple databases depending on some kind of heuristic (e.g. by
  user ID, or with archived content moved to a different server)
* Replication tricks, for example if you use MySQL's InnoDB for
  your data but replicate to a MyISAM server somewhere so you can
  use MySQL full-text indexing to search (Flickr used to do this).

I've probably missed some; please feel free to fill in the gaps.

We don't need to solve every problem, but we do need to provide
obvious hooks for how those problems should be solved. Sharding, for
example, is extremely application specific. I don't think Django
should automatically shard your data for you if you specify 'sharding
= True' on a model class, but it should provide documented hooks for
making a custom decision on which database connection should be used
for a query that allow sharding to be implemented without too much
pain.

Different applications on different databases on the other hand is
something Django should support out of the box. Likewise, master-slave
replication is common enough that it would be good to solve it with as
few lines of user-written code as possible (it's the first step most
people take to scale their database after adding caching - and it's a
sweet spot for the kind of read-heavy content sites that Django is
particularly suited for).

Proposed API


Here's my first attempt at describing a user-facing API.

First, we need a way of specifying multiple database connections.
Adrian has already expressed an interest in moving to DSNs rather than
individual settings, so I suggest something like this:

DATABASES = {
'default': 'mysql://foo:[EMAIL PROTECTED]/baz',
}

With multiple databases configured this could be:

DATABASES = {
'master': 'mysql://foo:[EMAIL PROTECTED]/mydb',
'slave1': 'mysql://foo:[EMAIL PROTECTED]/mydb',
'slave2': 'mysql://foo:[EMAIL PROTECTED]/mydb',
'archive': 'mysql://foo:[EMAIL PROTECTED]/mydb',
'default': 'master',
}

There are two types of connection string - DSNs and aliases. A DSN
contains '://' while an alias does not. Aliases can be used even
within the DATABASES setting itself, as with 'default' in the above
example.

It should be possible to use a DSN that has not been defined in the
DATABASES setting. As a result, I propose that anywhere in Django that
accepts a connection alias should also accept a DSN or even a raw DB-
API compliant connection object.

The QuerySet.using() method
---

Next, we need a way of telling Django which connection to use. I
propose a new queryset method as the lowest level way of doing this,
called 'using':

qs = Article.objects.filter(published__lt = ...).using('archive')

"using(alias_or_connection_or_dsn)" simply tells the QuerySet to
execute against a different connection, by updating its
internal .connection attribute.

Other options for this method name include:

with_db()
with_connection()

I preferred "using()" as it reads nicely and doesn't contain an
underscore.

using() represents the lowest level user-facing API. We can cover a
common case (different applications on different databases) with the
following:

class Article(models.Model):
...
class Meta:
using = 'articles'

This means "use the articles connection for all queries originating
with this model". I'm repurposing the term 'using' here for API
consistency.

Advanced connection selection
-

All of the other above use-cases boil down to one key decision: given
a 

Re: Proposal: {% doctype %} and {% field %} tag for outputting form widgets as HTML or XHTML

2008-09-10 Thread Simon Willison

On Sep 10, 3:32 am, Ville Säävuori <[EMAIL PROTECTED]> wrote:
> About the {% doctype %} tag, should we then maintain a (potentially
> long?) list of different doctypes and/or should there be a way to
> define your own?

I think we should maintain a list of doctypes - there really aren't
that many: xhtml1, xhtml1trans, xhtml1frameset, html4, html4trans,
html4frameset, xhtml11 and html5 should cover everything.

The current design of the {% doctype %} tag supports setting your own
custom doctype using the "silent" argument. You need to pick a
supported doctype that is closest to your own, then supress output
with "silent" and add your own instead:

{% doctype "xhtml1" silent %}

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Testing: making it easier to create mock Request objects

2008-09-09 Thread Simon Willison

On Sep 8, 6:03 am, akaihola <[EMAIL PROTECTED]> wrote:
> I couldn't find a ticket for this issue yet. Simon, mind if I create a
> ticket and dump your description of the issue there?

I've filed it here:

http://code.djangoproject.com/ticket/9002

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



Re: Ticket 8949: metronome/django-stones

2008-09-09 Thread Simon Willison

On Sep 10, 12:24 am, "Jeremy Dunck" <[EMAIL PROTECTED]> wrote:
> OK, enough noise on the naming.

(I really like metronome)

> Let's talk about what it should be and what should be measured.  :)
> (I suspect some devs already have a sketch regarding this stuff.
> Please share.)
>
> Do we want it to result in one big number like python/Lib/test/pystone.py?

I don't know much about benchmarking, but it seems to me it would be
most useful if we got one big number and about a dozen other numbers,
one for each category of performance testing. That would make it
easier to see if changes we made had an effect on a particular
subsystem, and also ties in nicely to your next point:

> Do we want to provide hooks for apps to supply something to stones for
> site-specific stone testing?

That seems sensible. It's like unit testing - we'll need code that
finds and loads the benchmarks for Django core, so we may as well get
it to look in user applications as well.

As for what we measure, I think to start off with we just go with the
basics: startup, request cycle, template processing, signals and ORM.
If we get the wrapper mechanism right it will be easy to add further
stuff once we have those covered.

> Also, what about things that affect downstream performance, but don't
> affect our runtime, like the HTTP Vary header?

I say we ignore those entirely. Other tools like YSlow can pick up the
slack there.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Proposal: {% doctype %} and {% field %} tag for outputting form widgets as HTML or XHTML

2008-09-09 Thread Simon Willison

Back in March there was a discussion about providing a way to output
django.forms widgets as HTML (at the moment they always use XHTML,
which leads to nastyness on sites using an HTML doctype):

http://groups.google.com/group/django-developers/browse_thread/thread/5f3694b8a19fb9a1/

On the plane back from DjangoCon I implemented the {% doctype %} and
{% field %} tags I proposed in that thread as custom template tags in
an application called "django_html". You can grab the code from here
and try it out:

http://code.google.com/p/django-html/

svn checkout http://django-html.googlecode.com/svn/trunk/django_html
django_html

(put django_html somewhere on your python path and add it to
INSTALLED_APPS)

I'm pretty confident this is the right approach. What do people think?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: multi-delete and edit form+changelist unification

2008-09-08 Thread Simon Willison

On Sep 8, 5:36 am, Erik Allik <[EMAIL PROTECTED]> wrote:
> I'm glad this came up, because I would also like to recommend  
> considering an admin interface for models that use django-mptt. I know  
> django-mptt is an external project but I think many people are using  
> django-mptt as it's currently the most popular tree solution available  
> for Django.
>
> What do people think?

I think that should be part of django-mptt, not part of Django itself.
If the admin needs a new customisation hook to make this easier then
that hook should definitely be added.

I've created a custom changelist for django-mptt in the past just by
over-riding the ModelAdmin queryset() method to return
self.model.tree.all() and applying a custom template. Is there
something more than that that you need to do?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: multi-delete and edit form+changelist unification

2008-09-08 Thread Simon Willison

On Sep 8, 2:46 am, Julien Phalip <[EMAIL PROTECTED]> wrote:
> I don't think this would be too hard to implement either. The URL
> routing would have to be redesigned though, as it is currently not
> very flexible. Maybe something like the following to edit multiple
> objects on the same page:http://www.mysite/admin/myapp/mymodel/1;2;3/

I don't think that's necessary. If inline edits are possible on the
changelist page, the URLs can stay the same as they are at the moment
- right now, the changelist page has incredibly powerful querystring
based URLs that can filter on almost anything that can be done with an
ORM .filter() call. Your above example would look like this:

http://example.com/admin/myapp/mymodel/?id__in=1,2,3

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



Re: Testing: making it easier to create mock Request objects

2008-09-07 Thread Simon Willison



On Sep 7, 10:03 pm, akaihola <[EMAIL PROTECTED]> wrote:
> I couldn't find a ticket for this issue yet. Simon, mind if I create a
> ticket and dump your description of the issue there?

Go for 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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Templates extending themselves cause infinite recursion

2008-09-06 Thread Simon Willison

I wrote up a work-around for this issue a while ago. If you need to be
able to over-ride your "base.html" template with a new template also
called "base.html" you can do it by adding an overall parent directory
to your TEMPLATE_DIRS setting which allows you to provide a fully
qualified path to the template you want to over-ride. Here's the full
explanation: http://code.djangoproject.com/wiki/ExtendingTemplates
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Multiple weblogs or catecorized news

2008-08-19 Thread Simon Willison

On Aug 19, 1:39 am, "Tom Tobin" <[EMAIL PROTECTED]> wrote:
> (And you know, I still think we'd be better off with
> "django-YES-THIS-ONE" and "django-NO-THE-OTHER-ONE".  Or perhaps a tad
> more seriously, something like "django-community" and "django-core" —
> otherwise we'll be fighting this battle forever.)

django-internals sounds good to me, though I've used up all of my
capital already as far as renaming things is concerned ;)
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: More secure user password reset

2008-06-28 Thread Simon Willison

On Jun 28, 11:21 pm, Luke Plant <[EMAIL PROTECTED]> wrote:
> MD5 is 8 chars shorter.  Do we really need SHA-1? If I understand
> correctly, the only known vulnerability with MD5 is the ability to
> force collisions, but that will not help an attacker in this case.
> The only thing that an attacker can influence at all in the string
> being hashed is the timestamp, and it is limited to a few chars.

Good point, well made - MD5 should be fine (I suggest leaving that
justification in a comment somewhere to fend off the inevitable
complaints).

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: More secure user password reset

2008-06-28 Thread Simon Willison

On Jun 28, 10:01 pm, "Scott Moonen" <[EMAIL PROTECTED]> wrote:
> If you add the timestamp into both the hash and the token then you can
> achieve a more granular expiration policy.

That's the approach I use for djangopeople.net - the problem is that
including the timestamp lengthens the URL yet further. I actually use
a hex representation of the number of days since 2001/1/1 as a short
representation of a timestamp, which at least knocks it down to just 3
characters:

ORIGIN_DATE = datetime.date(2000, 1, 1)

hex_to_int = lambda s: int(s, 16)
int_to_hex = lambda i: hex(i).replace('0x', '')

def lost_url_for_user(username):
days = int_to_hex((datetime.date.today() - ORIGIN_DATE).days)
hash = md5.new(settings.SECRET_KEY + days + username).hexdigest()
return '/recover/%s/%s/%s/' % (
username, days, hash
)

def hash_is_valid(username, days, hash):
if md5.new(settings.SECRET_KEY + days + username).hexdigest() !=
hash:
return False # Hash failed
# Ensure days is within a week of today
days_now = (datetime.date.today() - ORIGIN_DATE).days
days_old = days_now - hex_to_int(days)
if days_old < 7:
return True
else:
return False


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



Re: More secure user password reset

2008-06-28 Thread Simon Willison

On Jun 28, 12:29 pm, Luke Plant <[EMAIL PROTECTED]> wrote:
> https://example.com/reset/34-7127f83ebf8ce7ed22bdc50a50572a30
>
> i.e.
>
> https://example.com/reset/{uid}-{hash}

I've been playing with this a bit and the one thing that was
concerning me is that the UID on large sites can end up being quite
long, potentially busting the 72 character length limit for the
overall URL. What do you think about using base36 encoding for the
UID? That can significantly shorten the number of URL characters
needed to represent large numbers:

>>> int_to_base36(23452)
'i3g'
>>> int_to_base36(234524)
'50yk'

This would also be a neat excuse to get base36 support in to
django.utils, further emphasizing Django's philosophy of really caring
about URLs. (base32, where 0, o, i, l and 1 are omitted as being too
easily confused, would be useful as well: 
http://crockford.com/wrmg/base32.html).
If you have to include an ID in a URL encoding it to take up less
space (and make its ID-ness a bit less obvious) is a handy trick - see
TinyURL, YouTube and Reddit for examples.

A further micro-optimisation is to leave out the hyphen entirely,
since an SHA-1 hash is always 40 characters long (we should probably
use that instead of MD5). You can cut off the last 40 characters and
use what's left as the base-36 UID.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: More secure user password reset

2008-06-28 Thread Simon Willison

On Jun 28, 7:58 pm, "Adi J. Sieker" <[EMAIL PROTECTED]> wrote:
> <[EMAIL PROTECTED]> wrote:
> > That's absolutely ingenious - that approach gets my vote. I think I'll
> > switch DjangoPeople over to that.
>
> and to have the token expire you could add the date of the following day  
> into the hash.
> That way the token is valid for max 48 hours.

Aah, I see what you mean - so when you check the hash you'd check it
using today's date, then if that fails check with tomorrow's date,
then if that fails announce the hash to be invalid. Neat, although it
isn't very flexible - if people want a policy that says the link will
work for 6 hours you'd need a different mechanism entirely.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: More secure user password reset

2008-06-28 Thread Simon Willison

On Jun 28, 1:39 am, "Scott Moonen" <[EMAIL PROTECTED]> wrote:
> I don't think it's necessary to implement this in such a way that additional
> server state is stored.  Instead, you could let the confirmation token be a
> hash of the internal user state -- including, most importantly, the user
> password's salt and encrypted values.  That way, the valid confirmation
> token is 1) known only to the server (the User 'password' field is not
> externalized), 2) able to be computed at any time without being stashed
> anywhere, 3) constant until the user changes their password, and 4)
> guaranteed to change whenever the password is actually changed.

That's absolutely ingenious - that approach gets my vote. I think I'll
switch DjangoPeople over to that.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: More secure user password reset

2008-06-27 Thread Simon Willison

On Jun 28, 1:12 am, Luke Plant <[EMAIL PROTECTED]> wrote:
> > [EMAIL PROTECTED] said the following:
> > I'd suggest making the code to change the password a one-use-only
> > item though, so that even if someone did sniff the code, it'd be
> > useless after that.
>
> The problem with this is it requires state on the server, which means
> extra database models, and on top of that those tables will need cron
> jobs to clear them out or something.

Here's the way I usually solve this problem: send out a link that
looks like this:

https://example.com/reset/1214612777-34-7127f83ebf8ce7ed22bdc50a50572a30

There are three components to this link: the timestamp that the link
was sent out, the user's ID and an md5 hash of (timestamp + user_id +
SECRET_KEY). The timestamp is used to enforce a policy that says you
must follow the link within 24 hours of it being sent out. The md5
hash guards against tampering.

When the user clicks the link, they are taken to a one-time screen
that asks them to enter and confirm a brand new password.

With the above scheme you don't have to store state on the server and
you don't have to generate a random password for the user.

For added bonus points, instead of sending the timestamp as a full
base 10 integer use hexadecimal and the number of days since the epoch
- that allows you to represent the time in just a few characters which
can mean your entire reset URL fits within the 72 character line limit
imposed by bad e-mail clients such as Outlook (which can't handle URLs
that wrap).

You can try this scheme out for yourself by going through the lost
password recovery process on djangopeople.net:

http://djangopeople.net/lost/

I've got code for this lying round which I'd be happy to donate if
people agree this is the right approach.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Call for testing: streaming uploads (#2070)

2008-06-26 Thread Simon Willison

On Jun 26, 8:14 pm, "Jacob Kaplan-Moss" <[EMAIL PROTECTED]>
wrote:
> Documentation of the new features is can be found in
> ``docs/upload_handling.txt`` 
> orhttp://code.djangoproject.com/git/?p=django;a=blob_plain;f=docs/uploa

Just a small thing:

"""
Like any data supplied by the user, you shouldn't
trust that the uploaded file is actually this type. You'll still need
to
validate that the file contains the content that the content-type
header
claims -- "trust but verify."
"""

That's not "trust but verify" - that's "distrust and verify". You're
not trusting the content-type header at all!

The next line mentions verifying the charset of the uploaded file as
well. It would be useful to provide an example of code that confirms
that something is valid utf-8 here:

try:
chunk.decode('utf8')
except UnicodeDecodeError:
# It's not valid utf8

A link to http://chardet.feedparser.org/ would be useful here as well.

Finally, a question: from reading the documentation it isn't clear how
you would go about implementing an Ajax file progress bar - to build
one of those, you need to know how large the browser claims the file
will be right at the start of the stream (so you can calculate the
percentage done). Does a FileUploadHandler object have access to the
content length sent by the browser?

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Context support for simple_tag #7462

2008-06-16 Thread Simon Willison

On Jun 16, 10:00 am, Julien Phalip <[EMAIL PROTECTED]> wrote:
> I have just added a patch that allows a simple_tag to receive the
> context as first argument, like inclusion_tag already does. It is
> backward compatible.
>
> I'd like to get some feedback on the code, so feel free to check it
> out [1].

Looks great to me. With the addition of some regression tests to prove
that it works and doesn't break the old behaviour I'd love to see this
checked in.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: In-Browser Testing with TestCase

2008-06-14 Thread Simon Willison

On Jun 14, 12:26 am, Devin <[EMAIL PROTECTED]> wrote:
> So to integrate Selenium tests with the test framework already in
> place, I've added live server support for TestCase for ticket 
> 2879.http://code.djangoproject.com/ticket/2879#comment:27

That's pretty cool. Any chance you could provide an example of a test
that uses Selenium to show how it works? Presumably you're using the
Python driver for Selenium RC?

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Current request, object and action as fields of ModelAdmin instances (newforms-admin branch)

2008-06-10 Thread Simon Willison

On Jun 1, 8:20 am, "Yuri Baburov" <[EMAIL PROTECTED]> wrote:
> So, how about an idea of adding request, object, and action to
> ModelAdmin instances in newforms-admin code rather than in user code
> and refactoring newforms-admin code based on this decision?

We've used that exact trick recently at work, for implementing finely
grained permissions where a user should only be able to select from a
subset of the available options in a foreign key relationship box. To
do this, you need to use the formfield_for_dbfield method to alter the
choices for that particular field based on the current request.user
object.

We solved it the same way you did - by stashing the request object at
the beginning of the change_view method - so it would be nice if
newforms admin did that for us.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: newforms-admin customisation hook suggestions

2008-05-28 Thread Simon Willison

On May 29, 12:21 am, "Honza Král" <[EMAIL PROTECTED]> wrote:
> We had some discussions during PyCon in Chicago, the biggest issue we
> have with the hooks is the amount of code needed to change the widgets
>
> we talked with Joseph about something like widget-sets, a mapping prom
> either field, or perhaps field type to widgets, that could be easily
> defined - the simplest way to do that seems to be a dictionary
> { 'field_name': WidgetClass, ...}

I prefer methods over classes in a dictionary as using methods
provides a natural way to programatically decide on the widget based
on other factors. Generally speaking, the more information that's
available at the time of customisation (things like the request object
for example) the more flexible the API is.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



newforms-admin customisation hook suggestions

2008-05-28 Thread Simon Willison

We (GCap, large commercial radio company in the UK) have been
developing against the newforms-admin branch for a few months now, and
based on that experience I have a number of suggestions for simple
hooks that could be added to make it easier to customise.

1. Provide a custom template for a changelist / change form

You should be able to specify a custom template for those pages in
some way on the ModelAdmin object. At the moment select_template() is
used to allow custom templates to be specified, but that isn't nearly
flexible enough: it forces you to name your templates according to a
certain naming scheme (e.g. admin/events/venue/change_form.html) but
that means that you can't offer two admin interfaces with different
templates for editing a specific thing, which is kind of the whole
point of newforms admin allowing you to set up more than one admin
site. It also forces you to keep your templates in an admin/ hierarchy
which can be a bit limiting.

There are two potential solutions to this. The first is to have a
change_form_template option on the ModelAdmin:

class EventAdmin(ModelAdmin):
change_form_template = 'foo/bar/event_change_form.html'

The other is to have the template provided by a method which can be
over-ridden:

class EventAdmin(ModelAdmin):
def change_form_template(self, object=None):
return select_template(['foo.html', 'bar.html'])

Either look OK to me - the second is probably better as it lets you
run a bit of logic to decide which template to use.

Another benefit of this approach: it makes it easier to extend the
default admin template without fear of running in to the dreaded
template recursion problem.

Custom templates for ModelAdmins is absolutely my number one request
for newforms admin. It would make a huge number of customisations a
great deal easier (we have a UED guy who keeps on coming up with
genuinely good ideas for tweaks to our various admin screens).

2. Better hooks for custom form fields (esp. ForeignKey choices)

Every time I write a formfield_for_dbfield method I want to strangle a
kitten. I am not alone; this is pretty much the consensus among the
developers I work with. There really, really needs to be a better way
of doing per-form-field customisations.

One extremely important example is being able to alter the choices in
a ForeignKey or ManyToMany field, as discussed on this ticket:

http://code.djangoproject.com/ticket/3987

This is critically important because one of the big new features in
newforms-admin is the ability to do row-level permissions, thanks to
the extremely neat has_change_permission / has_change_permission /
has_delete_permission hooks and the ability to over-ride the queryset
for a changelist.

Unfortunately this doesn't go quite far enough. If you're dealing with
row level permissions ("user X can edit article Y") you also need to
be able to restrict foreign key relationships. User X might only be
allowed to assign an article to 4 out of the 30 categories on a site,
for example.

Ticket #3987 solves this in a reasonable way, but I'm not too keen on
the suggested dynamic method name (dynamic_FIELDNAME_choices). I
talked this over a bit with Stuart Langridge and we came up with the
following:

class BookAdmin(ModelAdmin):
...
def choices_for_author(self, request, book=None):
user = request.user
if not book:
# Creating a new book: return queryset for author choices
that
# the current user is allowed to assign
else:
# Editing an existing book; maybe do something a bit
different?

Using choices_for_FIELDNAME feels like it fits better with existing
Django conventions (like clean_FIELDNAME in newforms).

Then we thought, why not take this further? The most common things you
do with formfield_for_dbfield are setting a custom widget and setting
a custom formfield. So why not allow these:

def widget_for_author(...):
return CustomWidgetOfSomeSort()

def formfield_for_title(...):
return FormFieldOfSomeSort()

But what if you want to reuse the same method for many different
fields? We could provide fallback methods widget_for(self, dbfield),
formfield_for(self, dbfield) and choices_for(self, dbfield) to cover
that.

Yes, this means adding a lot of potential methods to ModelAdmin
(though note that since they are dynamically looked up we don't have
to add any real new methods to the actual class itself). I think
that's fine - it makes for an API that is clean, powerful and
extremely easy to understand.

I realise that some of the above could be mocked up just by writing a
custom formfield_for_dbfield method without patching newforms-admin at
all. I plan to do that as a proof of concept.

3. Make it easier to include custom CSS and JavaScript

By far the easiest way to tweak the admin is with a bit of unobtrusive
CSS and JavaScript. We're using jQuery a lot for this (to great
effect; for example, we've got a really nice drag-and-drop reordering

Re: Multiple database support

2008-05-23 Thread Simon Willison

On May 22, 6:53 pm, Ivan Sagalaev <[EMAIL PROTECTED]> wrote:
> Simon Willison wrote:
> > Thankfully Ivan Sagalaev's confusingly named mysql_cluster
>
> BTW does anyone have a suggestion how to rename it? I've picked
> mysql_cluster simply because I didn't know that there exists the thing
> named "MySQL Cluster" (no kidding :-) ).

How about mysql_masterslave or mysql_replicated (I prefer the second)?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Multiple database support

2008-05-22 Thread Simon Willison

I have to admit I'm slightly worried about the multi-database
proposal, because at the moment it doesn't seem to solve either of the
multi-db problems I'm concerned about.

The proposal at the moment deals with having different models live in
different databases - for example, the Forum application lives on DB1
while the Blog application lives on DB2.

I can see how this could be useful, but the two database problems that
keep me up at night are the following:

1. Replication - being able to send all of my writes to one master
machine but spread all of my reads over several slave machines.
Thankfully Ivan Sagalaev's confusingly named mysql_cluster covers this
problem neatly without modification to Django core - it's just an
alternative DB backend which demonstrates that doing this isn't
particularly hard: http://softwaremaniacs.org/soft/mysql_cluster/en/

2. Sharding - being able to put User entries 1-1000 on DB1, whereas
User entries 1001-2000 live on DB2 and so on.

I'd love Django to have built-in abilities to solve #1 - it's a really
important first-step on scaling up to multiple databases, and it's
also massively easier than any other part of the multi-db problem.

I wouldn't expect a magic solution to #2 because it's so highly
dependent on the application that is being built, but at the same time
it would be nice to see a multi-db solution at least take this in to
account (maybe just by providing an easy tool to direct an ORM request
to a specific server based on some arbitrary logic).

I may have misunderstood the proposal, but I think it's vital that the
above two use cases are considered. Even if they can't be solved
outright, providing tools that custom solutions to these cases can be
built with should be a priority for multi-db support.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: twill testing

2008-05-16 Thread Simon Willison

On May 15, 11:36 pm, Luke Plant <[EMAIL PROTECTED]> wrote:
> I've been using twill integrated into Django unit tests (as described
> here:http://www.djangosnippets.org/snippets/665/), but came across
> the problem that exceptions are hidden by Django's exception
> handling, so it's very difficult to tell what has gone wrong if you
> have a bug.  The patch attached adds a setting to allow exceptions to
> be propagated by BaseHandler.get_response().   Would anyone object to
> this?

I've been bitten by exactly this issue (using Twill, as it happens) so
a big +1 from me.

DEBUG_PROPAGATE_EXCEPTIONS might be a better name for the setting.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Rethinking silent failures in templates

2008-05-15 Thread Simon Willison

On May 14, 3:51 pm, Ken Arnold <[EMAIL PROTECTED]> wrote:
> 4. Other tags and filters, like include, ssi, and truncatewords (from
> a quick scan) that perform some function that could fail, should mark
> that failure very clearly in the output. (Those two currently do, but
> the error string is easy to miss if buried in a mess of other code.)
> 5. Variable lookups, and everything else, never cause render() to
> fail, but insert an easy-to-catch and easy-to-bypass error string in
> the output.

There are a few problems with inserting error output in the template
rather than raising an exception, the most important of which is that
you won't get an HTTP 500 error code so the problem won't be caught in
your server logs. Also, there are a number of situations where the
error output won't be visible in the browser - if it occurs within a

Re: Rethinking silent failures in templates

2008-05-14 Thread Simon Willison

On May 14, 3:02 pm, George Vilches <[EMAIL PROTECTED]> wrote:
> On May 14, 2008, at 9:58 AM, Simon Willison wrote:
> > Silent errors are bad. If we were to remove them, how much of a
> > negative impact would it have on the existing user base?
>
> I suspect that a lot of people actually rely on this behavior, and it
> would be devastating to them.

Thinking about it some more you're right - I'm sure there are lots of
cases where people are relying on things like the following:

{{ article.something.title }} - outputs text if article is there,
fails silently otherwise

Which leaves us in a tricky situation. A global settings.py variable
for "throw errors on missing template variables" is a bad idea as it
kills application portability (the PHP magic_quotes problem again - if
your application expects that setting off and mine expects it on I
can't import your app in to my environment). There might be something
we can do with warnings, but it could still end up pretty messy. Needs
more thought.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Rethinking silent failures in templates

2008-05-14 Thread Simon Willison

Hi all,

Some time in late 2003, Adrian and I decided that errors in templates
were best handled silently - the idea was that it would prevent
untrained template editors from being able to 500-error a site with a
typo.

Is it too late to reconsider this decision, four and a half years
later? I can't think of a single time this feature has helped me, and
plenty of examples of times that it has tripped me up.

Today's example: a  tag that shouldn't have been
blank. The code looked like this:



If you look at Django's URL tag implementation, you can see why:

http://code.djangoproject.com/browser/django/trunk/django/template/defaulttags.py?rev=6996#L364

The code catches the NoReverseMatch exception and silences it,
outputting an empty string instead.

Silent errors are bad. If we were to remove them, how much of a
negative impact would it have on the existing user base?

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: sql_queries does not include all the sql statements

2008-04-29 Thread Simon Willison

On Apr 29, 9:32 am, leopay <[EMAIL PROTECTED]> wrote:
> oh,I make a mistake the first query is
>
> Entry.objects.all()[0:1]
>
> but still have the problem

This is to do with lazy evaluation of querysets. I've posted an
explanation on django-users - please reply there if you have any more
questions.

http://groups.google.com/group/django-users/browse_thread/thread/1d3cd3bcd0bb3e6b

Best regards,

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



Re: How expensive are tests?

2008-04-27 Thread Simon Willison

On Apr 27, 6:37 am, "Russell Keith-Magee" <[EMAIL PROTECTED]>
wrote:
> - The slow operation is resetting the database. As far as I know,
> there isn't much that can be done about this. No matter which way you
> do it, deleting a whole lot of data then re-establishing database
> structure is an expensive operation.

There's probably an obvious reason why this wouldn't work, but could
this be dealt with by running each test suite inside a transaction and
rolling back at the end of it instead of committing? Transactions can
be nested so theoretically it shouldn't interfere with Django's other
transaction related features.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Aggregate Support to the ORM

2008-04-27 Thread Simon Willison

On Apr 27, 1:59 am, "Russell Keith-Magee" <[EMAIL PROTECTED]>
wrote:
> Its mostly there as a convenience for the really simple cases. There
> some duplication in typing annotate(avg_height=Avg('height'), so the
> shortcut is a convenience. IMHO, this is the sort of thing could be
> easily explained in the documentation for each aggregate function.

Seems reasonable. I think I'd like to see the explicit syntax
introduced first in the docs just so people aren't confused by the
very first example, but avoiding the duplication in
avg_height=Avg('height') is a worthy goal.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Queryset-refactor branch has been merged into trunk

2008-04-27 Thread Simon Willison

On Apr 27, 4:04 am, Malcolm Tredinnick <[EMAIL PROTECTED]>
wrote:
> I merged queryset-refactor into trunk just now. This was changeset
> r7477.

Fantastic! Congratulations, and thank you.

One of my favourite new features is the ability to more easily see the
SQL that is going to be run against the database for a given queryset,
using the new .query and .query.as_sql() methods:

>>> print Woo.objects.filter(name='Hello').query
SELECT "demo_woo"."id", "demo_woo"."name", "demo_woo"."when",
"demo_woo"."description" FROM "demo_woo" WHERE "demo_woo"."name" =
Hello
>>> print Woo.objects.filter(name='Hello').query.as_sql()
('SELECT "demo_woo"."id", "demo_woo"."name", "demo_woo"."when",
"demo_woo"."description" FROM "demo_woo" WHERE "demo_woo"."name" = %s
', ('Hello',))

Is there any reason these aren't documented? I was going to add them
to the wiki page but I wasn't sure if they were intended as internal-
only features that may change in the future.

Also, how hard would it be to get the __str__() representation of a
Query to be escaped using the current database's escaping syntax? It
seems like it could be a bit of a fiddle as Python's DB-API doesn't
require database engines to expose that ability, but it would be
extremely useful for testing - it would mean you could copy and paste
SQL directly from Python's interactive prompt (or from the Django SQL
query log) and paste it in to a mysql interactive shell, which would
help with debugging tricky SQL.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Aggregate Support to the ORM

2008-04-26 Thread Simon Willison

On Apr 26, 12:33 pm, "Russell Keith-Magee" <[EMAIL PROTECTED]>
wrote:

> So - here's a slightly modified proposal. Last time this topic came up
> on django-dev, Justin Fagnani made an interesting suggestion which I
> think will answer your objections, and leaves open some interesting
> possibilities for userspace extension. Rather than the
> column__aggregate=alias syntax:
>
> >>> Student.objects.all().annotate(
>Avg('height'), tallest=Max('height'), avg_friend_age=Avg('friend__age')
> )
> The raw idea - the aggregates themselves are tied up into functions
> (Avg, Max, etc) that are constructed as an object. The argument to the
> aggregate is the query column, using the standard double-underscore
> notation if necessary to cross tables. In QS-RF, this syntax is being
> used for cross-table order_by() clauses, so there is an analog there.

I like this a lot - makes much more sense to me than the other syntax,
and I think I prefer it to my proposed dictionary based syntax as
well.

> If the aggregate function is provided as an anonymous argument (e.g.,
> Avg('height')), then the aggregate is asked to provide an appropriate
> alias - for example, Avg() might use 'avg__%s' % field_name. If the
> aggregate function is provided as a kwarg, the kwarg name is used as
> the alias.

Is it necessary to provide an anonymous argument syntax at all? Seeing
just annotate(Avg('height')) left me confused as to what the alias
would be until I read your further explanation. Is there any harm in
requiring the user of the API to always explicitly specify their alias
using keyword argument syntax? Unless there's a really good reason to
provide default aliases I think requiring explicit aliases would be
perfectly reasonable ("explicit is better than implicit").

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Aggregate Support to the ORM

2008-04-26 Thread Simon Willison

On Apr 26, 7:34 am, "Ian Kelly" <[EMAIL PROTECTED]> wrote:
> On Fri, Apr 25, 2008 at 11:40 PM, Russell Keith-Magee
>
> <[EMAIL PROTECTED]> wrote:
> >  >  Have you considered syntax that looks like this instead? :
> >  >  >>> Students.objects.all().aggregate({'average_height': 'height__avg})
> >  >  > {'average_height' : 1.43}
>
> >  My issue with this syntax is that every aggregate requires 4 extra
> >  punctuation characters (two parentheses, two quotes), and all you
> >  really get in return is to reverse the order so that you get
> >  result=operation type syntax... except that you can't use the =
> >  operator. It also doesn't have any particular analogs with existing
> >  ORM syntax.
>
> I would say it has a pretty good analog:
>
> >>> Student.objects.all().extra(select={'floor_height': 'floor(height)'})

That was my thinking exactly. I think the cognitive dissonance
involved in height__avg='average_height' is much greater than that in
({'average_height': 'height__avg}). Sure, it's new ORM syntax but it's
also a new ORM feature. Overloading the existing syntax to do
something that's actually quite different feels really strange to me.

name__contains='blah' is field-name__comparison-operator = input-to-
comparison-operator

height__avg='average_height' is field-name__aggregate-function = alias
under which the result should be known

I think the syntax looking similar here is misleading rather than
helpful.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Maybe DEBUG=True should only record the last N SQL queries?

2008-04-21 Thread Simon Willison

On Apr 20, 11:23 pm, "[EMAIL PROTECTED]" <[EMAIL PROTECTED]> wrote:
> -1 for the reasons that James Bennett stated above.  That it crashes
> and burns in production is actually a feature in this case.

If we want to crash and burn if you use DEBUG=True in production we
should do that explicitly, not as a side effect of another feature. I
think there is enough real-world evidence that people are being
tripped up by this for legitimate reasons (running import scripts in
development mode, for example) that it's worth fixing.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: SecureForm in newforms

2008-04-19 Thread Simon Willison

On Apr 17, 5:04 pm, "Jeremy Dunck" <[EMAIL PROTECTED]> wrote:
> Middleware is easy to set and forget.  Is there a reason not to make
> SecureForm the default, and InsecureForm for people using Ajax?  ;-)

I'm pretty sure we can handle the Ajax case by not doing CSRF token
checks if request.is_ajax() is True. As far as I can tell there's no
way to make a CSRF attack with a custom "X-Requested-By:
XMLHttpRequest" HTTP header (unless your application has an XSS hole,
in which case CSRF tokens are useless anyway).

I've been thinking about this a LOT recently. Here are a few notes:

1. You only need a SafeForm (I like that term as it has similarity to
the "safe" temple filter) if you are dealing with a POST /and/ your
functionality is restricted to identified users in some way (generally
users that have an active session).
2. The constructor for a bound form needs to take the request object,
not an explicit request.POST. This is because the CSRF token
validation will need access to the request session or cookies in order
to confirm that the returned token is valid for the current user.
Since SafeForm is only intended for request.POST I see no problem in
just taking the request object:

bound_form = MySafeForm(request)

3. This is the point I'm stuck on: should the implementation add a new
hidden form field to the field definition or insert it in some other
way? I'd like to make everything completely transparent to anyone
using SafeForm, so I'd rather not even add a new field to form.fields
or form.base_fields.
4. How does Django know where to put the hidden field in the generated
HTML? Do we force people to add {{ form.csrf_token }} somewhere in
their form HTML? The alternative would be to add {% form ... %} and {%
endform %} template tags which replace explicit  tags and ensure
a CSRF token is included. Added bonus: if our form object has
knowledge of its action="" attribute we can include that in the
generation of the CSRF token, thus reducing the damage possible if a
token leaks to an attacker somehow (because a leaked token will be
valid for a specific user, action URL and time period).
5. There's a UI design problem here: what message do we show people if
they trip our CSRF detection? If our tokens are limited to a 24 hour
period for example then there's a chance someone might open a page in
a browser tab, then actually submit the form more than 24 hours later.
We need to show a regular form validation error along the lines of
"Please re-submit the form." This introduces another problem: where do
we display this error? Do we have to ensure people remember to add
{{ form.non_field_errors }} to their template (which they'll certainly
forget to do). Again, having a {% form %} tag helps here as it gives
us somewhere to cram the error in.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Maybe DEBUG=True should only record the last N SQL queries?

2008-04-19 Thread Simon Willison

I've noticed that a LOT of people get bitten by the problem where
every SQL statement is logged if DEBUG=True, resulting in huge memory
consumption after a while. This problem seems particularly common for
import scripts, which are often run in development (hence with DEBUG
on) and can involve thousands of queries.

Of course, this behaviour is documented... but I think it's reasonable
to expect that many people will miss that part of the docs.

What do people think of having the debug SQL log limited to only
storing the last N queries, with N set to something sensible like 200
by default? This behavior could be controlled by a setting so if
people want to log everything they can:

DEBUG_SQL_LOG_LIMIT = 200 # Set to 0 to disable logging, set to None
for unlimited logging

This seems to me to be more sensible default behaviour.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Template.render() should accept a dictionary, not just a Context object

2008-04-11 Thread Simon Willison

Here's something that has been quietly bugging me about Django for /
years/:

Context() is an implementation detail of the template engine. Having
to instantiate a Context just to pass it to render() is unnecessary
boilerplate (and means you have to import another symbol as well).

Template.render() should continue to accept a context object, but it
should also have the option of accepting a dictionary - and if it gets
one, should quietly upgrade it to a Context before passing it down the
render chain.

http://code.djangoproject.com/browser/django/trunk/django/template/__init__.py#L174

Suggested implementation:

def render(self, context):
"Display stage -- can be called many times"
if not isinstance(context, Context):
context = Context(context)
return self.nodelist.render(context)

This is backwards compatible and would make the template system that
tiny bit nicer to use.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



new-forms admin shouldn't throw error when a model is registered twice #6776

2008-04-11 Thread Simon Willison

http://code.djangoproject.com/ticket/6776

newforms-admin raises an AlreadyRegistered exception if you attempt to
register a model with admin.site twice. Unfortunately, due to the
different places and ways in which a models.py file can be imported
it's extremely easy to trigger this accidentally, and difficult to
debug when you do.

The code in question is here:

http://code.djangoproject.com/browser/django/branches/newforms-admin/django/contrib/admin/sites.py#L78

if model in self._registry:
raise AlreadyRegistered(
'The model %s is already registered' % model.__name__
)
self._registry[model] = admin_class(model, self)

Is there any reason we can't just ignore attempts at repeat
registrations here?

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: If form_for_model is deprecated, what is its replacement?

2008-04-08 Thread Simon Willison

On Apr 7, 8:19 pm, "Jacob Kaplan-Moss" <[EMAIL PROTECTED]>
wrote:
> On Mon, Apr 7, 2008 at 9:09 AM, Joseph Kocherhans <[EMAIL PROTECTED]> wrote:
> >  I'm also mostly in agreement here.
>
> As am I. Syntax is tough, of course; here's my two cents::
>
> form = ModelForm(model=Person, exclude=["pay_grade"])

Looks great to me.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: If form_for_model is deprecated, what is its replacement?

2008-04-07 Thread Simon Willison

On Apr 7, 2:15 pm, "James Bennett" <[EMAIL PROTECTED]> wrote:
> >  I'd still like to see form_for_model stay (or be replaced by the above
> >  or similar) rather than being deprecated.
>
> Personally I don't see much call for it; dynamically building a
> ModelForm is easy enough, and maintaining two distinct ways to do the
> same thing just feels like clutter.

I think this actually comes down to a wider philosophical point about
declarative syntax. Declarative syntax based on metaclasses has become
quite a popular pattern in Django, but it comes at the expense of easy
dynamic creation of objects. The ModelForm example in this thread is
one example; dynamically constructing a newforms instance is another.
I would rather see declarative syntax as syntactic sugar over a more
traditional API than declarative syntax as the only way to do things
(and crazy closure-based dynamic class hacks to support the dynamic
creation case).

Newforms is a particularly good example - there are many cases in
which it makes sense to dynamically assemble a form at runtime
(providing one form field for each day of the current month, for
example) but the current implementation is focused on declarative
forms - dynamically adding fields requires knowledge of newforms
internals. I'd rather have a set of documented APIs for building a
form up one field at a time, with a metaclass-based declarative
wrapper over the top that makes use of that underlying API.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: If form_for_model is deprecated, what is its replacement?

2008-04-07 Thread Simon Willison

On Apr 7, 2:15 pm, "James Bennett" <[EMAIL PROTECTED]> wrote:
> >  I'd still like to see form_for_model stay (or be replaced by the above
> >  or similar) rather than being deprecated.
>
> Personally I don't see much call for it; dynamically building a
> ModelForm is easy enough, and maintaining two distinct ways to do the
> same thing just feels like clutter.

I think this actually comes down to a wider philosophical point about
declarative syntax. Declarative syntax based on metaclasses has become
quite a popular pattern in Django, but it comes at the expense of easy
dynamic creation of objects. The ModelForm example in this thread is
one example; dynamically constructing a newforms instance is another.
I would rather see declarative syntax as syntactic sugar over a more
traditional API than declarative syntax as the only way to do things
(and crazy closure-based dynamic class hacks to support the dynamic
creation case).

Newforms is a particularly good example - there are many cases in
which it makes sense to dynamically assemble a form at runtime
(providing one form field for each day of the current month, for
example) but the current implementation is focused on declarative
forms - dynamically adding fields requires knowledge of newforms
internals. I'd rather have a set of documented APIs for building a
form up one field at a time, with a metaclass-based declarative
wrapper over the top that makes use of that underlying API.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: If form_for_model is deprecated, what is its replacement?

2008-04-07 Thread Simon Willison

On Apr 7, 1:05 pm, Simon Willison <[EMAIL PROTECTED]> wrote:
> I suppose I could dynamically
> construct a ModelForm subclass at runtime (any pointers on how to do
> that, including dynamically creating the inner class called "Meta",
> would be welcome) but for the above the existing form_for_model()
> function is a whole bunch more intuitive.

To answer my own question, it turns out dynamically constructing a
class is really easy if you take advantage of closures:

def my_form_for_model(model_class):
class Form(ModelForm):
class Meta:
model = model_class
return Form

I'd still like to see form_for_model stay (or be replaced by the above
or similar) rather than being deprecated.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



If form_for_model is deprecated, what is its replacement?

2008-04-07 Thread Simon Willison

form_for_model is marked as deprecated but ModelForm does not appear
to be a full replacement for it. Given an arbitrary model class (i.e.
one that is defined at runtime, not at "compile" time) there is no
clear way of creating a form from it using the ModelForm mechanism.

Here's what I am doing at the moment:

from django.db import models
from django import newforms as forms

model_name = 'sites.Site' # Actually comes from outside the system
model_class = models.get_model(*model_name.split("."))

form_class = forms.form_for_model(model_class)
form = form_class(data_dict)
if form.is_valid():
form.save()
...

This works great, since form_for_model() works at runtime. With
ModelForm, the model class for which I want a form has to be baked in
to the class in the source code. I suppose I could dynamically
construct a ModelForm subclass at runtime (any pointers on how to do
that, including dynamically creating the inner class called "Meta",
would be welcome) but for the above the existing form_for_model()
function is a whole bunch more intuitive.

I like the syntactic sugar provided by declarative APIs such as
ModelForm, but I think it's important to provide a non-declarative
alternative for people who need to dynamically construct something at
runtime rather than baking the details in to their source code.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: signals

2007-12-23 Thread Simon Willison


On 23 Dec 2007, at 12:39, ivan.illarionov wrote:

> As I know PyDispatcher project has evolved into Louie project and is
> actively maintained by the same author. The code is *not* ugly, is
> closer to Django coding style and has a lot of improvements.
> http://louie.berlios.de/
>
> Even more, I replaced content of django.dispatch with louie code,
> renamed all imports `from louie` to `from django.dispatch` and
> everything worked without any errors.

Have you benchmarked Louie compared to PyDispatcher at all? From  
looking over their documentation they don't seem to have made any  
changes that would result in a substantial speed increase.

Cheers,

Simon Willison

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



Re: newforms-admin and django.contrib.auth

2007-12-17 Thread Simon Willison


On 17 Dec 2007, at 08:08, James Bennett wrote:

> This means the default implementation can happily use
> django.contrib.auth and the existing is_staff flag and permission
> system, but that using something else is as easy as subclassing and
> overriding the right methods. And with a little refactoring to remove
> the direct reliance on the LogEntry and Message models, it would be
> easy to run the Django admin without django.contrib.auth, simply by
> plugging in whatever auth/permissions system you like in the
> appropriate places.

I love it. This would make it much cleaner to integrate the Django  
admin with existing authentication schemes (LDAP, Active Directory,  
whatever custom SSO mechanism Oracle sell to big companies) without  
having to create a new Django user for every existing SSO user and  
keep the two in sync somehow. Sounds like it wouldn't be an enormous  
change either.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Django 1.0 features -- the definitive list

2007-12-08 Thread Simon Willison


On 8 Dec 2007, at 20:14, Kevin Menard wrote:

> Shifting to a more personal stance, I never cared much for the term
> "Web 2.0".  It seems too gimmicky.  That's largely the impression I
> get with a Django 2.0 without a prior Django 1.0.

The other problem with Django 2.0 is that Rails just released their  
2.0 - which means that a Django release will look like an attempt to  
catch up on the version number - obviously not the case. If we wanted  
to make a statement about Django's maturity that statement could be  
equally well served by jumping straight to 1.5. This would also  
maintain the meaningfulness of version 1.0 - once past 1.0, backwards  
compatibility with the APIs is guaranteed.

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



Re: Django 1.0 features -- the definitive list

2007-12-04 Thread Simon Willison


On 4 Dec 2007, at 13:26, bobj wrote:

> Simon - These are GREAT!!! Ideas. The regular expression based URL
> dispatching  replacement has been something I personally have been
> thinking about for some time.  I would be interested in helping with
> this If you put together a proposal. One URL implementation worth
> considering is "Routes" ( http://routes.groovie.org ). I have used
> Routes for web applications and I think it is easy to grok. Have you
> taken a look at Routes?

I like Routes in principle, but the way it has the concept of a  
"controller" baked in to it didn't sit very well with me. I can't  
imagine it would be hard to use it without controllers though.

I'm generally pretty happy with regular expressions, but I watched  
Scott Guthrie's presentation on the ASP.NET MVC framework a few weeks  
ago (it's really interesting, they've taken a bunch of ideas from  
Django and it gets name-checked in the presentation) and one of the  
things he noted is that there are developers (especially in the  
Microsoft ecosystem) who never really got comfortable with regexps. I  
don't want those people to be turned away from Django on the first  
page of the tutorial. He also described the ASP.NET MVC syntax for  
URLs, which looks like this:

search/[query]
product/[id]

http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc- 
framework-part-2-url-routing.aspx

While I personally prefer the power of regexps, I can see how the  
above would make it much easier for developers just beginning to get  
their feet wet with Django. We can always enlighten them with the  
power of regular expressions once they're hooked. If URL handling is  
interchangeable we can have the best of both worlds. Incidentally,  
allowing URL logic to be swapped out was an initial design goal back  
when we put the URL stuff together - we were worried about  
performance, but when we benchmarked it turned out that Python can  
run through a list of a hundred or so regular expressions in less  
than 0.01 seconds.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Django 1.0 features -- the definitive list

2007-12-03 Thread Simon Willison


On 3 Dec 2007, at 08:15, James Bennett wrote:

> At that point I'd wonder why Django had any machinery for
> request/response processing, middleware, etc., given that what you're
> describing is more neatly handled by just writing a WSGI application
> and taking advantage of the existing tools.

Because WSGI is a horrible API for developers. I'd love to see Django  
request/response become a simple developer-friendly wrapper around  
WSGI, provided we gained rather than lost flexibility and power in  
the process.

I'd like to see the distance between a Django application (or a  
Django view) and WSGI as small as possible. Imagine if you could drop  
a Django view in to any WSGI container just by applying a WSGI-to- 
Django-view wrapper of some sort. Or, imagine taking a WSGI  
application, wrapping it up as a Django view and deploying it  
straight in to a Django URL configuration.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Interim release before 1.0?

2007-12-03 Thread Simon Willison

On 3 Dec 2007, at 15:45, Malcolm Tredinnick wrote:
> -1 from me.
>
> I've already responded at least three times on the users list why this
> wouldn't be a good idea. We should indeed do a release after that  
> stuff
> is merged. It will be called 1.0 (or 2.0 or whatever).

Ta, should have looked there first.

http://groups.google.com/group/django-users/browse_thread/thread/ 
83dcb4df7a061316/10ef4070aa9b5539

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Interim release before 1.0?

2007-12-03 Thread Simon Willison

It's fantastic that 1.0 (or whatever it ends up being called) is now  
under serious discussion, but are there any plans for a numbered  
release before then? I've been asked by a few people if they should  
be running svn or a numbered release - with auto-escaping now in  
trunk it seems a new numbered release would be a good idea some time  
soon (probably before the queryset refactor or newforms admin  
branches are merged).

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Django 1.0 features -- the definitive list

2007-11-30 Thread Simon Willison

On Nov 30, 6:33 am, "Adrian Holovaty" <[EMAIL PROTECTED]> wrote:
> What am I forgetting?

It's probably too big a feature to start talking about now, but I'd be
really interested in seeing Django applications (in particular the
URLconf part) unified with the concept of a Django view, so a Django
application is a callable that takes a request object and returns a
response - and in fact an entire Django deployment can be boiled down
to that. This has a number of advantages:

1. At the moment, middleware applies globally to the whole site. This
is bad: often you'll want a piece of middleware to apply just to one
or two of the applications that a site is composed of. If views and
applications (and projects) had a unified API then middleware could be
redefined to apply at any level of the stack. View middleware wouldn't
make so much sense here, but Request and Response middleware would.
2. We always said that the regular expression based URL dispatching
should be replaceable by other methods if required. Having url
dispatch as just another view function would give us that for free.
I'd love to have a simpler alternative to the regexp method that is
more friendly for developers who haven't fully grokked regular
expression syntax yet.

If there's enough interest in the DEP idea I'd be happy to write up
this proposal more formally.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Suggestion: DEPs - Django Enhancement Proposals

2007-11-30 Thread Simon Willison

On Dec 1, 2:02 am, Simon Willison <[EMAIL PROTECTED]> wrote:
> Here's an idea that's been kicking around in the back of my head for
> far too long: Django Enhancement Proposals, or DEPs.

For further context it's worth reading PEP 1, which describes PEPs and
how they work:

http://www.python.org/dev/peps/pep-0001/

I don't think DEPs would need to be quite as strictly structured
(there's a fair amount of administrative overhead involved in PEPs),
but we could certainly adapt a slightly more lightweight version of
the PEP system.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Suggestion: DEPs - Django Enhancement Proposals

2007-11-30 Thread Simon Willison

Here's an idea that's been kicking around in the back of my head for
far too long: Django Enhancement Proposals, or DEPs. At the moment,
large changes to Django (auto escaping, queryset refactor etc) are
discussed in quite an ad-hoc way - if you want to stay completely up
to date on them you need to be following mailing lists, tracking
branches and talking directly to the developers. It would be great if
these changes had a slightly more formal structure, and in particular
a single document that described the design decision and what was
going on.

We're already doing this on the wiki for most things so it wouldn't be
an enormous change, but formalising it a bit could help make things
clearer. Python's PEPs work brilliantly; could the same idea work for
Django as well?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Django 1.0 features -- the definitive list

2007-11-30 Thread Simon Willison

On Nov 30, 6:33 am, "Adrian Holovaty" <[EMAIL PROTECTED]> wrote:
> I think we ought to call the release 2.0.

I'm -0.5 on this (if that's possible). I understand the thinking
behind it, but "1.0" isn't an arbitrary version number - it has a very
specific meaning: "the APIs are frozen, it's safe to build things
without worrying that backwards compatibility will be broken". That's
what we've been telling people for the past couple of years, and as a
result I feel it would be odd to use 2.0 to make the statement that
version numbers are meaningless after all.

I think that the release of v1.0 combined with the publication of the
Django Book will result in a serious uptick in interest in the project
(and that's not saying that there isn't plenty of interest already). I
wouldn't want to see some of that interest diverted by confusion over
version numbers.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Request data encoding

2007-08-02 Thread Simon Willison

On Aug 2, 9:39 pm, "Jacob Kaplan-Moss" <[EMAIL PROTECTED]>
wrote:
> Yuck, clients that don't speak HTTP correctly make me angry.
>
> Reading the RFC, though, I see that since HTTP 1.0 made "charset"
> optional, it remains so in HTTP 1.1, and we're supposed to "guess" and
> use ISO-8859-1 like you're doing in your code snippet. I suppose that
> means that Django's request object should do pretty much what you've
> done in this snippet.

This is a totally ridiculous flaw with the HTTP spec - you literally
have no reliable way of telling what encoding a request coming in to
your site uses, since you can't be absolutely sure that the user-agent
read a page from your site to find out your character encoding!

One really smart trick you can do is this: attempt to decode as UTF-8
(which is nice and strict and will fail noisily for pretty much
anything that isn't either UTF-8 or ASCII, a UTF-8 subset). If
decoding fails, assume ISO-8859-1 which will decode absolutely
anything without ever throwing an error (although if the content isn't
ISO-8859-1 you'll end up with garbage). I tend to call this the Flickr
trick, because of the lovely big letters here:
http://www.flickr.com/services/api/misc.encoding.html

If it really matters, you can use Mark Pilgrim's chardet library to
detect the most likely encoding based on statistical analysis:
http://chardet.feedparser.org/


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



Re: Autoescaping: good time?

2007-08-02 Thread Simon Willison

On Aug 1, 7:56 pm, "Tom Tobin" <[EMAIL PROTECTED]> wrote:
> Set autoescaping on by default for anything ending in ``.html`` (and,
> perhaps, ``.htm``), and off otherwise.

I've been thinking about this a bit, and it seems like it could work
well if it was done the other way round - basically, autoescaping is
on for everything EXCEPT templates where the template name is known /
and/ it ends in .txt. I don't think this would be too hacky to
implement - templates that are loaded (as opposed to constructed from
a string) already know their template name as part of the template
error handling code; all that would be needed would be a way to tell a
newly created template to default to autoescape off, and then a bit of
code in the relevant template loader to special case for template
names ending in .txt.

Generally I'm really glad to see that most people have come round to
autoescaping being on by default now. I personally don't see it as a
way of protecting newbie developers so much as it's a way of
protecting all developers from one tiny mistake blowing the security
of their application wide open.


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



Re: Volunteering for "Week in Review" postings

2007-05-25 Thread Simon Willison

On May 25, 1:25 pm, "Clint Ecker" <[EMAIL PROTECTED]> wrote:
> Should they be every week regardless of whether there were 1 or 10
> worthy developments, or should the author wait until X number of good
> links have been culled until a post is made, no matter the time in
> between posts. I might be getting a little pedantic here, please let
> me know. ;)

I think you'd be excellent for the job. I suggest aiming for weekly
updates even if there are only two or three things to report, but
skipping weeks entirely if nothing has haeppened. With the rate Django
is progressing at the moment I don't see that happening too often
though.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Changing django.contrib.auth to make passwords optional

2007-05-11 Thread Simon Willison

On May 11, 4:23 pm, Niels <[EMAIL PROTECTED]> wrote:
> > Or you could use the traditional
> > Unix password invalidator -- "!" -- which might be more mnemonic for
> > some people and is easier to pick out of a data dump than a space (and
> > will also never be a valid string, since we use '$' as a separator).
>
> So how about "openid$" ??

I think I'll go with ! (thanks Malcolm - I didn't know that piece of
Unix arcania). openid$ assumes that the only reason you would leave
the password field blank is if you were using OpenID, but there are
plenty of other reasons you might have a blank password field (using
LDAP or Yahoo! BBAuth or similar for example).

Cheesr,

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Changing django.contrib.auth to make passwords optional

2007-05-11 Thread Simon Willison

On May 11, 3:40 pm, Martin Winkler <[EMAIL PROTECTED]> wrote:
> > Certainly Oracle treats them empty string as equal to NULL. But does
> > that mean you can't put an empty string in a "not NULL" column in
> > Oracle?
>
> Exactly. If you want to insert something meaningless into a column that
> has a NOT NULL constraint in oracle, then you have to put at least
> one space character into it.

So does that mean that I should store a single blank space in the
password field to represent "no password set"?


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



Re: Changing django.contrib.auth to make passwords optional

2007-05-11 Thread Simon Willison

On May 11, 7:50 am, Ivan Sagalaev <[EMAIL PROTECTED]> wrote:
> > At the moment, django.contrib.auth does not support creating a user
> > account without setting a password.
>
> Why not generate a random one? It won't break an ability to authenticate
> using OpenID or any other backend for that matter. I've used this
> approach with my OpenID auth backend and didn't encounter any downsides.

The problem with using a random password is that you can't answer the
question "does this account have a password set?". I need to be able
to answer that question because my OpenID implementation allows users
to associate mupltiple OpenIDs with a single account. I want to let
them delete associations as well, but prevent them from deleting the
very last association unless they have set a password for their
account (to stop them from locking themselves out).


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



Changing django.contrib.auth to make passwords optional

2007-05-10 Thread Simon Willison

I'm working on a new component for my Django OpenID package which will
provide support for associating one or more OpenIDs with a
django.contrib.auth User. As part of this, I want to include the
ability to register for a new user account using an OpenID instead of
a password.

At the moment, django.contrib.auth does not support creating a user
account without setting a password.

OpenID is not the only use case where password-less accounts might be
warranted. Any application where authentication takes place against an
external source - for example, authenticating against an existing LDAP
provider - would also benefit from being able to create Django user
accounts without setting a password.

I propose the following changes:

1. The 'password' field in the User model should be altered to have
blank=True.

This would allow us to set blank passwords as an empty string. It
would not require existing installations to make any schema changes as
the column would still be NOT NULL.

2. user.set_password(password) should be altered to accept 'None'

If None is passed to the function, a blank string will be stored
instead of an encrypted password.

3. user.has_password() should be added

A simple utility method which returns True if the user has a password,
False if they do not.

4. check_password should ALWAYS return False if no password is set

This should help protect us from introducing any security issues with
these changes.

Does this sound like a workable plan? If so, I'd like to get the
changes in as soon as possible so I can wrap up work on the next
version of the OpenID package.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: If there was massive security hole found in Django, are there plans in place to deal with it?

2006-08-10 Thread Simon Willison

James Bennett wrote:
> On 8/9/06, Jason Huggins <[EMAIL PROTECTED]> wrote:
> > I can see how a policy like that is "tricky"... What's to keep an evil
> > blackhat from subscribing to the very same list so he he knows when to
> > get busy cracking sites using the same information?
>
> I've been watching people go round and round about this in various
> places today, and I have to say that I can respect the Rails team's
> policy of not releasing full details of the vulnerability until after
> their users have had a little time to patch. Full disclosure still
> happens, but it's slightly safer for end users this way. A couple
> other open-source projects I've used/been involved with have followed
> a similar policy of "update ASAP, and we'll release details once
> people have had time to patch", and it's caused no harm that I've
> seen.

There are two principle reasons the Rails issue has gone over badly
with the community:

1. Forced upgrade to 1.1.5. This caused big problems for users on
versions of Rails older than 1.1.4 - people still using Rails 1.0 for
example. With hindsight, I think it's obvious to everyone that the
Rails team should have prepared patches for other affected versions
rather than forcing people to upgrade. Thankfull, Django security
policy already takes this in to account:

http://www.djangoproject.com/documentation/contributing/#reporting-security-issues
"Halt all other development as long as is needed to develop a fix,
including patches against the current and two previous releases."

2. The full disclosure problem. The argument against fully disclosing
the problem seems pretty solid: it's a serious exploit (it appears to
allow remote Ruby code execution) and they wanted to give Rails users a
head-start on the attackers. Here's the argument against (for those who
haven't been following along):

- The flaw can be found by running diff against 1.1.4 and 1.1.5. Any
half decent attacker could do this. The Rails team actually included a
red herring (an SQL injection unit test) to try to throw people off the
scent, but that was never going to hold back anyone with a modicum of
talent. Once one black hat had figured it out it would spread quickly
via underground mailing lists and IRC channels, leaving white hats at a
disadvantage.
- Because users didn't know what the flaw was, they couldn't evaluate
the solution to confirm that it was going to work. More importantly,
they had nothing to judge how urgent the upgrade was or if there was
some other short-term measure they could take to protect themselves.

The biggest complaints are due to a combination of the above factors.
The initial announcement stated that more versions of Rails were
affected than was actually the case. This resulted in some users
spending hours upgrading their applications, only to later find that
the version of Rails they were running was safe. This would not have
been an issue had full disclosure let them (or the community) analyse
the problem in more depth. It also wouldn't have been an issue if
patches had been released for older Rails versions.

Based on all that, I think the principle lesson from the whole thing is
that getting patches out for older releases is critically important.
Luckily this is already listed as Django policy. I doubt that full
disclosure would have been as much of an issue as it has if they had
got those patches out straight away.

Like Jeremy said, this stuff is hard.

Some good background reading on the Rails situation:

http://weblog.rubyonrails.org/2006/8/10/security-update-rails-1-0-not-affected
(the comments)
http://www.ruby-forum.com/topic/76671

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Default escaping -- again!

2006-07-28 Thread Simon Willison


On 28 Jul 2006, at 13:06, Todd O'Bryan wrote:

> What if we deprecated {{ }} and replaced it with an escape tag and a
> raw tag? It would keep backward compatibility, but would encourage
> people to use escaped strings unless they have a reason to use raw
> ones. I suppose we don't really have to deprecate it, but just
> discourage its use.
>
> {! !} seems perfect for raw, because the exclamation points emphasize
> that something bad could happen.
>
> {$ $} could be used for escaping, with the $'s designed to remind
> people of environment variables. This would be tag people are
> encouraged to use unless they need raw HTML text.

The above is nice and simple, but it only solves a subset of the  
problem that auto_escaping is designed to solve. The missing  
component is filters: for filters to be truly chainable, they need an  
awareness of if their input is escaped or not. The 'unorderedlist' vs  
'escaped_unorderedlist' discussion from a while back is a good  
example of that. This is covered in more detail in the proposal on  
the wiki.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Default escaping -- again!

2006-07-27 Thread Simon Willison


On 28 Jul 2006, at 01:50, Ahmad Alhashemi wrote:

> Default escaping couples the Django templates with HTML. I don't think
> that this is a good idea, even if HTML is, incidentally, the most
> commonly used language in templates, for the time being.

Here's an idea I don't think anyone has brought up yet: what if  
escaping was on by default for templates ending in .html and off by  
default for templates ending in .txt?

I'm not sure how I feel about this, seeing as we only recently made  
it so you had to specify the file extension. It seems to fit quite  
nicely though. That said, there may be problems getting it to work  
with alternative template sources.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Default escaping -- again!

2006-07-27 Thread Simon Willison

On 27 Jul 2006, at 21:01, Tom Tobin wrote:
> From what I recall of conversations on the subject, default behavior
> will not be changed to auto-escape.  Auto-escaping, under whatever
> proposal is accepted, will require some form of action to enable.

I like to think that's not set in stone yet. There's a lot of  
opposition to having it on by default, but I'm hoping there's a  
chance that people might start to change their minds once they've had  
the opportunity to try it out. I'm not going to push the point until  
it's ready to try though, and I think that arguing the point is  
pointless without running code to act as an example.

(Malcolm Tredinnick's patch looks like a really great bash at this;  
it's great that someone's taking the initiative and hammering out  
some code).

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Slides of Europython 2006?

2006-07-19 Thread Simon Willison


On 19 Jul 2006, at 15:43, David Larlet wrote:

> I'd like to know if it's possible to have access to django slides of
> Simon's conf at Europython 2006.

I've uploaded my slides to the conference site:

http://indico.cern.ch/contributionDisplay.py? 
contribId=26=9=44

They're a 22 MB PDF file.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: django-unicode conversion, first experiments, questions

2006-07-19 Thread Simon Willison


On 19 Jul 2006, at 15:30, Ivan Sagalaev wrote:

> I just thought that may be they shouldn't. If META is a reflection of
> CGI's environment that is derived from HTTP environment that is
> essentially in byte strings then I think META being unicode is may be
> useless and misleading.
>
> Instead the META can be declared as a low-level stuff that is needed
> only in custom cases. But we also have a public API: request.GET,
> request.POST, request.method. This API reflects the user data
> (urldecoded params, etc.) and should be unicode.
>
> What do you think of this idea?

I'm still on the fence. I agree that it makes sense for META to use  
bytestrings, but I'd really like the bias to be towards unicode  
strings where ever we can have them to reduce the confusion that  
might stem from having both bytestrings and unicode strings mixed  
together. I don't see any harm in META using unicode strings, whereas  
if it were to use bytestrings our documentation ends up being that  
little bit more confusing (we can't just claim everything is a  
unicode string).

If there are any practical disadvantages to META containing unicode  
strings then it should definitely use byte strings - but I'm not yet  
convinced that the disadvantages exist. I'm more than ready to be  
convinced otherwise though.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: django-unicode conversion, first experiments, questions

2006-07-19 Thread Simon Willison


On 19 Jul 2006, at 14:37, Gábor Farkas wrote:

> 1. request.META should contain raw bytestrings (like it's currently)
> 2. request.META should contain unicode strings. for QUERY_STRING, we
> should convert it to unicode using the 'ascii' charset. and we should
> not url-decode it.

request.META should contain unicode strings that directly reflect the  
underlying raw bytestrings - in other words, they're the raw  
bytestrings converted in to unicode by decoding as ASCII. We can do  
this because they should be encoded in ASCII in the first place.

request.META['QUERY_STRING'] should not be treated any differently  
from the other items.

request.GET on the other hand should be created by decoding stuff  
from QUERY_STRING using urldecoding and the charset specified by the  
browser.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: django-unicode conversion, first experiments, questions

2006-07-19 Thread Simon Willison


On 19 Jul 2006, at 13:19, Ivan Sagalaev wrote:

> Talking about QUERY_STRING... While the string itself is in ASCII  
> it has
> urlencoded data and there the encoding matters. As fas as I can see in
> practice browsers tend to encode those data in the same encoding as  
> the
> page from where those links come. So for decoding urlencoded
> QUERY_STRING I think it's reasonable to use DEFAULT_CHARSET.

We shouldn't be decoding QUERY_STRING in request.META at all - we  
should leave it as urlencoded ASCII. request.META is meant to give  
you access to the 'raw data' from the browser.

We do however need to take charset stuff in to account when creating  
the request.GET and request.POST arrays - that's where the query  
string should be parsed and unencoded and turned in to a set of name/ 
value unicode strings. The character encoding used for this data  
should be specified in a browser header; as a general rule, browsers  
submit data back to the server using the same character encoding that  
the page with the form on was sent as.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: django-unicode conversion, first experiments, questions

2006-07-19 Thread Simon Willison


On 18 Jul 2006, at 23:30, gabor wrote:

> 1. django publishes the whole environ dictionary as request.META. the
> environ dictionary is a normal byte-string dictionary. so, should we
> convert it to unicode so that the request.META dictionary only  
> contains
> unicode strings?
>
> 1.a: if yes, how? some things like QUERY_STRING and REQUEST_METHOD are
> relatively simple how to convert, but what should happen to the other
> server-related stuff like HTTP_X_FORWARDED_HOST? should we convert  
> them?
> if yes, with what encoding? ascii? iso-8859-1?

The environment stuff is all taken from the CGI specification.

The original CGI specification makes no mention of character encoding  
at all:

http://hoohoo.ncsa.uiuc.edu/cgi/interface.html

An attempt was made in 1999 to update the spec to the status of an  
RFC. A draft was prepared but expired at the end of that year without  
being accepted as a formal RFC - so it doesn't have any real  
standing. It did however specify ASCII as the encoding for use in the  
CGI protocol:

http://cgi-spec.golux.com/draft-coar-cgi-v11-03-clean.html

In the absence of anything better than that, I think it's safe to  
assume that CGI environment variables should always be ASCII encoded.

I think that request.META should contain unicode strings based on the  
principle of least surprise - if everything else is unicode, it  
should be too. So we assume ASCII as the encoding for that stuff and  
turn it in to unicode strings.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Generic View Bug and Issues

2006-07-18 Thread Simon Willison


On 18 Jul 2006, at 16:19, Tyson Tate wrote:

> Is there any way I can get a response on this? I really hate to be
> annoying and pedantic, but the following problems are literally show-
> stopper problems for my Django projects and they're holding up what
> is otherwise a working project. I would really appreciate something -
> anything!

Can you provide code (a model + your view configuration) to allow the  
bug to be easily reproduced?

Thanks,

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Do we need an escaped version of unordered_list?

2006-07-14 Thread Simon Willison

On 14 Jul 2006, at 03:05, Malcolm Tredinnick wrote:

> Is there any alternative to creating an escaped_unordered_list tag?  
> (Any
> better name for this tag? It's too long)

Yes. Implementing the auto escape proposal.

> [Note: useful responses to this question do not include "auto-escaping
> would be nice". That is not the issue here and it gets tiring reading
> it.]

I would argue that it is the issue here - more specifically, the  
current auto_escape proposal is designed to tackle this exact  
problem, among others.

http://code.djangoproject.com/wiki/AutoEscaping

The solution lies with the way the proposal flags strings as escaped  
or unescaped. The unordered_list tag would escape items passed in to  
it based on the current state of the auto_escape flag combined with  
whether or not the item was flagged as already having been escaped.

Output an unordered list with each item escaped:
{{ list_of_unsafe_strings|unordered_list }}  - assumes default for  
the current template is autoescape on

Output an ordered list where each item can contain HTML:
{% autoescape off %}
{{ list_of_unsafe_strings|unordered_list }}
{% endautoescape %}

Alternatively, if the fact that the items contain safe HTML is known  
by the view:

c = Context({
   'items': map(escapedstr, items)
})

And in the template:

{{ items|unordered_list }}

Because the items have all been flagged as escaped, the auto escaping  
mechanism will skip them and the safe HTML will be rendered as required.

unordered_list was one of the use cases I was thinking about when I  
drew up the proposal. I should probably update the wiki page to  
reflect that.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Test framework for end-user applications

2006-07-13 Thread Simon Willison


On 12 Jul 2006, at 02:28, Malcolm Tredinnick wrote:

> I approached things from a different direction, though, more
> concentrating on how to unit test templates and views (as in not
> requiring a full end-to-end application setup in order to test  
> them). So
> it's actually a orthogonal to what you are proposing here and fits in
> nicely.

I've been thinking about unit testing templates and views on-and-off  
for the past few months. Here's the bulk of my thinking.

The best way of running tests against a Django application, to my  
mind, is to run a "fake" web server (i.e. one that doesn't actually  
bind to a port) around the application. This fake server acts as a  
test harness. Tests can then create HttpRequest objects (probably a  
subclass called something like TestHttpRequest), pass them to the  
Django application, get back an HttpResponse object and run  
assertions against that.

There's just one problem with this approach: while running assertions  
against an HttpResponse object is adequate, the ideal situation would  
be to run assertions against the template context as well. If you  
just run assertions against the HttpResponse object you end up having  
to process the HTML in some way to work out if the test has passed.  
What you really want to be able to do is this (pseudocode):

send_get('/polls/1/')

assert_response_status(200)
assert_response_contains('This is poll 1')

assert_template_rendered('poll_detail.html')
assert_template_context_match('poll.id', 1)
assert_template_context_match('poll.title', 'poll 1')

(These function names are deliberately horrible - I haven't thought  
about a nice API for this yet).

The first line above fakes sending a GET request to /polls/1/. The  
next line checks that the response status code was 200, and the line  
after checks that the response body contained 'This is poll 1'. So  
far, all of these things can be done just using an HttpResponse object.

The next three lines assert that the correct template was rendered,  
and check that the template context contained the expected data. This  
isn't possible with just an HttpResponse - the template and context  
have been rendered and forgotten by the time the HttpResponse is  
returned.

TurboGears and Rails don't have this problem (in fact Rails is where  
the idea for running assertions against the template context comes  
from) because they couple their template systems to the view. We  
don't want to do that in Django.

The solution I've been thinking about involves Django's event  
dispatch system. I think we should be firing an event when a template  
is rendered. The testing harness can then listen out for that event  
and use it to capture the template and context, meaning you can run  
assertions against them. This keeps our template system decoupled  
while letting us write tests against the template activity within the  
view functions.

I hope the above makes sense. I'll try to follow up later with a  
better idea of how I think the assertions API should look.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Unicodification of Django

2006-07-06 Thread Simon Willison


On 5 Jul 2006, at 15:21, Jacob Kaplan-Moss wrote:

> Er, no -- that PEP was actually rejected.  My impression is that the
> str/unicode distinction won't be eliminated until Py3k.

Guido's keynote at EuroPython confirmed that - one of the big changes  
in Py3K (which is now planned for an initial release within two  
years) is unicode strings throughout.

Doesn't help us very much though :/

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Proposal: default escaping (and branch request)

2006-07-06 Thread Simon Willison


On 6 Jul 2006, at 05:09, SmileyChris wrote:

> Does the template source *need* to provide information on what is
> escaped or not?
>
> The view is handling a lot of the output format anyway, I personally
> don't see a problem with looking there to see how a template is being
> escaped.
>
> Then again, I guess escaping is "presentation logic" and maybe it
> should be coupled to the template source... any other thoughts,  
> people?

Templates should be reusable across different views - "generic  
templates" are a very useful concept that Django does not yet really  
address. Escape logic in the views may be inaccessible to the  
template designers, which leaves them unaware of whether or not they  
need to deal with escaping.

I just got back from EuroPython, and one of the hot topics there was  
templating systems. One thing that caught me by surprise when  
discussing this issue is how Django is actually the exception rather  
than the norm in terms of the escaping issue - Zope templates,  
Quixote and Kid all escape variable output by default.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Request for history: incoming data processing

2006-06-28 Thread Simon Willison


On 28 Jun 2006, at 17:45, Malcolm Tredinnick wrote:

> But I wanted to find out if there was a reason for this behaviour  
> in the
> original design (Adrian? Jacob? Simon?). Did you have something in  
> mind
> to work around it? Or was it a case of "never came up before"?

I can't think of any good reason other than "never came up before".  
Actually, I remember that we had to do a bunch of extra work to get  
file uploads working which should have been the hint that the  
abstraction wasn't ideal.

At any rate, with REST APIs being the new hotness this needs to be  
fixed pronto - keeping things backwards compatible of course.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Unicodification of Django

2006-06-28 Thread Simon Willison

On 28 Jun 2006, at 15:32, Adrian Holovaty wrote:

> The only big problem I see is that it could confuse the (unfortunately
> large) mass of programmers who don't understand Unicode yet. That is a
> big potential pitfall.

That's very true. The documentation overhead will be considerable. It  
should be possible to get most things to Just Work, but the edge  
cases will be hard to explain. A classic example is working with a  
Python interactive prompt and trying to "print article.title" when  
title contains higher order unicode characters - this causes ascii  
decode errors in terminals that haven't been correctly configured.

Having been bitten by unicode problems in the past while dealing with  
RSS feeds (from feedparser, which always returns unicode strings) I'd  
definitely love to see this feature in Django, and I'd be willing to  
help out with the effort.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Unicodification of Django

2006-06-28 Thread Simon Willison

On 28 Jun 2006, at 14:43, Andrey Golovizin wrote:

> Unicode awareness may seem not a big issue for English-speakers  
> (for whom
> plain ASCII is perfectly enough :)), but for others (like me) it's  
> of crucial
> importance.

I don't think that's true. On today's Web there's no guarantee at all  
that you won't get comments (for example) posted by someone with a  
non-ascii character in their name. If you want to consume data from  
other services (RSS feeds are a particularly good example here)  
character encoding stuff is also bound to turn up.

I seem to remember that last time people looked at unicode with  
Django one of the sticking points was database stuff - some of the  
adapters are unicode-string aware, others choke and burn. That  
shouldn't be an insurmountable problem though, it would just require  
a bit more logic in the database adapters.

If we're going to add unicode support it really should happen before  
1.0. One point that's worth considering is how much of a marketing  
coup out-of-the-box unicode would be, especially in comparison to  
Ruby and Rails, neither of which are very good at this stuff.

As far as engineering goes, developing a water-tight test suite seems  
like a critical component for confidently adding unicode support.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: URL confs should take callables as well as strings

2006-06-26 Thread Simon Willison


On 26 Jun 2006, at 11:51, Daniel Poelzleithner wrote:

> What i still missing is a possibility to use other values to find the
> right view (most likely the http host header).
> I suggested http://code.djangoproject.com/ticket/1192 but Adrian  
> doesn't
> like it for some reason I can't understand :)
>
> Anyway, maybe there could be some nice and clean way to use  
> callables in
> urlconfs to allow such things.

The original intention with the URL resolver was for it to be easily  
swappable for alternative implementations that use a different  
mechanism (we were worried that lists of regular expressions wouldn't  
be fast enough, but that turned out not to be a problem). Along the  
way that abstraction seems to have got lost, but it would be nice to  
get it back so that alternative URL resolving mechanisms could be  
dropped in if required. That's a subject for another thread though.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: URL confs should take callables as well as strings

2006-06-26 Thread Simon Willison


On 26 Jun 2006, at 11:04, Malcolm Tredinnick wrote:

> Another thing we need to document better here, because this claim  
> is not
> quite correct (didn't you help write this?).

D'oh. No, the pattern prefixing stuff was nothing to do with me. Not  
sure how I missed that trick!

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



URL confs should take callables as well as strings

2006-06-26 Thread Simon Willison
I've been playing around with making the URL resolver accept a  
callable in addition to accepting 'module.blah' strings, and I think  
it's a big improvement.

The change itself is very simple - when a URL is resolved, callable 
(callback) is used to decide if the callback is already a callable  
object; if it is, it is called directly rather than being resolved in  
to a module/method first. It ends up being a two line patch.

This then makes urls.py a whole lot more flexible. Here's an example:

def redirect(url):
 def fn(request):
 return HttpResponseRedirect(url)
 return fn

urlpatterns = patterns('',
 (r'^$', redirect('/HomePage/')),
 (r'^(\w+)/$', 'djwiki.views.wikipage'),
 ...
)

That redirect function can either exist in urls.py itself, or can be  
dropped straight in to djange.conf.urls.defaults (since all urls.py  
files start with 'from django.conf.urls.defaults import *').

Allowing callables in urlconfs opens up a whole bunch of other  
opportunities as well. Setting up generic views could be made much  
less fiddly:

from django.views.generic import ListDetail
from models import Things

thingviews = ListDetail(Things.objects.all())

urlpatterns = patterns('',
 (r'^$', thingviews.object_list),
 (r'^(\d+)/$', thingviews.object_detail)
 ...
)

In fact, a whole bunch of stuff that currently has to be done with  
global settings or duplicated arguments could be handled in the URL  
configuration Python file instead.

Another advantage that this offers is a more elegant alternative to  
the common prefix problem. Right now, if you are using a bunch of  
views from a certain module the recommendation is to do the following:

urlpatterns = patterns('path.to.some.moduleviews',
 (r'^$', 'index'),
 (r'^(\d+)/$', 'detail')
 ...
)

This only works if EVERY view comes from the same module - if you  
want to mix and match views from different modules you're back to  
specifying the full path for each one (or futzing around with include 
()). With callable views, you can do the following instead:

from path.to.some import moduleviews
from path.to.other import otherviews

urlpatterns = patterns(,
 (r'^$', moduleviews.index),
 (r'^(\d+)/$', moduleviews.detail)
 (r'^blah/$', otherviews.blah
 ...
)

One last benefit: This is a step towards being able to create single- 
file Django applications - ideal for one-off throwaway applications  
and hello-world examples.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---


urlresolvers.callable.py.diff
Description: Binary data




Re: Proposal: default escaping (and branch request)

2006-06-22 Thread Simon Willison


On 22 Jun 2006, at 04:50, James Bennett wrote:

>> following that, I think Django should, of the two options, cover the
>> majority, which I believe is "escape by default" and allow {%
>> autoescape off %}. For the sake of security, I'm really hoping to see
>> escaping automatically turned on.
>
> Has the world honestly learned not one single solitary thing form
> PHP's magic_quotes fiasco? Autoescaping all output by default is
> something that is unequivocally not acceptable.

Magic quotes escaped all INPUT by default, and did it based on a  
global setting (which meant code couldn't be moved from one  
environment to another if their global setting differed). The lessons  
I take from this are:

1. Never have a global setting that might make code impossible to reuse
2. Don't make assumptions about how input data will be used.

Auto escaping output is not affected by either of these.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Better input validation (was Proposal: default escaping)

2006-06-22 Thread Simon Willison

On 22 Jun 2006, at 08:48, James Bennett wrote:

> For given values of "validate", yes. It is, however, easy to write
> validator functions which will reject anything that looks like HTML,
> and HTML is the most important threat.

I disagree that it's easy to write that kind of validator function -  
and I think trying to do so is a mistake. What if I want to post a  
comment on a forum like this?

"""
Don't worry Timmy, links in HTML are easy - just use LINK TEXT
"""

That looks like HTML - because it is! But I had no intention of  
messing anything up.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Proposal: default escaping (and branch request)

2006-06-20 Thread Simon Willison

On 20 Jun 2006, at 16:25, James Bennett wrote:

> Security by annoyance is security that people learn to hate and turn
> off as soon as they can, so in the end it doesn't really make them any
> more secure than they were before.

Agreed - which is why I want to try it in a branch and see if it's  
actually annoying :)

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Proposal: default escaping (and branch request)

2006-06-20 Thread Simon Willison


On 20 Jun 2006, at 15:11, Michael Radziej wrote:

> But, looking at the recent bugs in the Admin:
>
> 2006, __str__() output not escaped in breadcrumbs and filters
> 2152, username was not escaped
>
> Perhaps neither of this would be fixed with auto-escaping. But I  
> want to
> emphasize that bugs like this happen all the time, are hard to spot  
> and
> are inherently dangerous. If you escape too much, you'll spot it  
> easily,
> and not much harm has been done.

This is exactly why I'm for auto escaping - these bugs sneak in all  
over the place; they aren't something that only affects careless or  
newbie developers. I bet there's a bunch hiding in the current Django  
source code.

If we did have it as an opt-in thing rather than being turned on by  
default we'd also have to include a bunch of stuff in the docs saying  
"we really, really strongly suggest that you opt-in to this".

I'm actually on the fence as to having it on by default - my gut  
feeling is that it's a good idea, since every framework ever that  
hasn't done it has been plagued by XSS problems. That said, I don't  
think we can get a really good feel for how it works in practise  
until we can actually play with working code - which is why I want to  
build it in a branch (until we're sure that it works nicely it  
definitely shouldn't be inflicted on people following trunk).

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



Re: Proposal: default escaping (and branch request)

2006-06-20 Thread Simon Willison


On 20 Jun 2006, at 12:15, Michael Radziej wrote:

> Perhaps it's also a good idea to add an attribute `raw` to the  
> class `escaped`, so that
> you can always access the raw string when it is necessary. In some  
> circumstances, such
> as when you pass a complete html table in the context, this could  
> simply raise an error.

I'm not sure that this would be a problem. That's why I want to get a  
branch up and running - a lot of the problems with this stuff are  
hard to predict until you're running actual code.

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-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers
-~--~~~~--~~--~--~---



<    1   2   3   >