Re: Class based generic views in 1.3?

2010-06-02 Thread Roald
Maybe I've missed the reason, or it's just too late to change, but why
not using a class itself (so basically its __init__ method) as a view.
I'm using something like this in my projects (as a base class):

class View(HttpRequest):
def __init__(self, request, *args, **kwargs):
...
super(View, self).__init__(self.content())
...

You can find it (the commit at time of writing) on
http://github.com/roalddevries/class_based_views/blob/10b5e4016c755164c20126f14870c41dc88b9c03/views.py.

An advantage of this is that url patterns of the form ('...', my_view)
can be user, where my_view is just a class derived from View. I also
think that the solution to redirection (lines 32-39) is pretty
elegant.

I'm looking forward to your comments.

Cheers, Roald

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



Re: Class based generic views in 1.3?

2010-06-03 Thread Roald
On 2 jun, 23:22, Luke Plant  wrote:
> On Wednesday 02 June 2010 16:08:24 Roald wrote:
> >     class View(HttpRequest):
> >         def __init__(self, request, *args, **kwargs):
> >             ...
> >             super(View, self).__init__(self.content())
> >         ...
>
> You mean:
>
>      class View(HttpResponse):
>          ...

That's what I meant, yes.

> One reason against this is it makes it harder to re-use other views
> from within the View.

I don't really understand what you mean. Do you mean re-using 'good'
old function-views?

> You are forced to mutate the 'self' instance of
> HttpResponse (or else use some nasty hack),

No nasty hacks, just mutate 'self' from inside its class instead of
from outside.

> rather than being able to
> simply return the HttpResponse that might be returned from a utility
> function or a sub-view.

The other options presented in this topic (using __call__, __new__ or
View.as_view) all have their drawbacks, and personally I think I like
__init__ best:
- the __call__-option requires a different interpretation of url
patterns
- the __new__-option is actually a hack, does unexpected things and
thus is less readable, and is I think more complex that the __init__-
option
- the static/class method option is not really an improvement over
global functions, and leads to url patterns with more 'boiler plate
code'
- the __init__-option is only as complex as any Django programmer
should understand.

But even if you think that using __init__ is more complex than writing
a utility function: no worries. Normally you will use it something
like this:

class myview(View):
template_file = 'myapp/template.html'

@property
def context_dict(self):
return {'authenticated':
self.request.user.is_authenticated()}

... which you can hardly call complicated.

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



Re: Class based generic views in 1.3?

2010-06-04 Thread Roald
On 3 jun, 19:33, Luke Plant  wrote:
> On Thursday 03 June 2010 08:59:31 Roald wrote:
> > > One reason against this is it makes it harder to re-use other
> > > views from within the View.
> > I don't really understand what you mean. Do you mean re-using
> > 'good' old function-views?
> Yes, or new ones, or any callable that returns an HttpResponse that I
> want to return.  It is quite a common pattern to have one view wrap
> another or *several* others, and also to use standard response objects
> in some utility function or 'sub view'. e.g.
>
> def my_view(request, *args):
>    if some_condition():
>       return some_view(request, *args)
>    elif other_condition():
>       return some_standard_response(request.user)
>    else:
>       ...
>       return render_to_response(...)
>
> def some_standard_response(user)
>     return HttpResponseRedirect(...)
>
> This would be massively uglified, at best, if we make View a subclass
> of HttpResponse.

You're right, I wouldn't know how to do this with __init__, and I
think I would choose for a simple function, or maybe __new__. On the
other hand: is that a problem? These classes are a solution to a
problem that I have with a lot of my views, but not with all. It's not
necessary to make every view a class.

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



Re: Class based generic views in 1.3?

2010-06-04 Thread Roald
On 4 jun, 12:10, Roald  wrote:
> On 3 jun, 19:33, Luke Plant  wrote:
> > On Thursday 03 June 2010 08:59:31 Roald wrote:
> > > > One reason against this is it makes it harder to re-use other
> > > > views from within the View.
> > > I don't really understand what you mean. Do you mean re-using
> > > 'good' old function-views?
> > Yes, or new ones, or any callable that returns an HttpResponse that I
> > want to return.  It is quite a common pattern to have one view wrap
> > another or *several* others, and also to use standard response objects
> > in some utility function or 'sub view'. e.g.
>
> > def my_view(request, *args):
> >    if some_condition():
> >       return some_view(request, *args)
> >    elif other_condition():
> >       return some_standard_response(request.user)
> >    else:
> >       ...
> >       return render_to_response(...)
>
> > def some_standard_response(user)
> >     return HttpResponseRedirect(...)
>
> > This would be massively uglified, at best, if we make View a subclass
> > of HttpResponse.
>
> You're right, I wouldn't know how to do this with __init__, and I
> think I would choose for a simple function, or maybe __new__. On the
> other hand: is that a problem? These classes are a solution to a
> problem that I have with a lot of my views, but not with all. It's not
> necessary to make every view a class.

I've thought about it a bit more, and from an object oriented point of
view, your 'my_view' should be a base class of 'some_view',
'some_standard_response' etcetera. ABCMeta gives us a way of adding
(abstract) base classes. In Python I think you would best describe
that with something like:


class my_view(HttpResponse):
__metaclass__ = ABCMeta

def __init__(self, *args, **kwargs):
print 'init my_view'

def __new__(cls, *args, **kwargs):
if some_condition():
return some_view(*args, **kwargs)
elif other_condition():
return some_standard_response(*args, **kwargs)
else:
...
return object.__new__(cls)


my_view.register(some_view)
my_view.register(some_standard_response)


This (or something like it) seems to be able to take the best of the
__new__ and __init__ options.

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



Re: Class based generic views in 1.3?

2010-06-17 Thread Roald
On 16 jun, 15:45, Ben Firshman  wrote:
> The request is passed round so methods look like views to decorators. 
> Magically dropping it for decorators seems a bit scary. :/

Just brainstorming: couldn't you have View derive from HttpRequest?
Then you get a request object as the first parameter of methods, and
you can apply decorators to them (untested):

class View(HttpRequest):
def __new__(cls, request, *args, **kwargs):
"""
make sure not to call HttpRequest.__init__ on the request
again,
since it has already been initialized
"""
request.__class__ = cls # or maybe make a copy of
request first
return request(*args, **kwargs)

@login_required
def __call__(request, *args, **kwargs):
return HttpResponse('')

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



Re: Class based generic views in 1.3?

2010-06-17 Thread Roald
On 17 jun, 12:16, Patryk Zawadzki  wrote:
> On Thu, Jun 17, 2010 at 11:53 AM, Roald  wrote:
> > On 16 jun, 15:45, Ben Firshman  wrote:
> >> The request is passed round so methods look like views to decorators. 
> >> Magically dropping it for decorators seems a bit scary. :/
>
> > Just brainstorming: couldn't you have View derive from HttpRequest?
>
> Would you seriously recommend people to extend "int" when they want to
> implement multiplication? :)

Nope. But the analogy doesn't hold.

First: this is just brainstorming. Maybe it inspires someone for a
better solution somehow. As you might know, I (still) favor deriving
from HttpResponse

Second: users will never extend HttpRequest directly, they will extend
View.

Third: It might be not even as weird as it looks on first sight.
There's nothing wrong with 'response = request.get_response()', so why
not just make 'get_response' the  'default function' of a request:
response = request(). I admint that the name View might nog be the
best in this case.

Fourth: still, this is just brainstorming.

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



Re: Class based generic views in 1.3?

2010-06-17 Thread Roald
On 17 jun, 15:32, Tom Evans  wrote:
> 1) With inheritance, you should be able to say Derived is-a Base,
I agree very much.

> eg
> 'a Car is-a Vehicle'. A view is NOT a response, however you wrap it
> up. A view is a generator that when called with a request, results in
> a response, whether it is a class based view, or a function based
> view. Does a view have headers or a mime type?
>
> Perhaps you need to start using different names for these classes,
> because inferring that 'a view is-a response' just sounds stupid.
I agree. So the question becomes: should we use views or http
responses. Personally, I think a view is a pretty abstract concept
('something that turns a request in a response'), and I would prefer
something more graspable.

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



ModelView

2010-07-12 Thread Roald
Hi all,


There is a discussion 'Class based generic views in 1.3?' in this
list. I would like to suggest an alternative: ModelViews. There
normally are multiple standard views associated with one model, and
such a class can take advantage of that. Its use should look something
like this:


* in urls.py:
(r'^blog/', BlogPostView),


* in views.py
class BlogPostView(ModelView):
class Meta:
model = BlogPost


The base class ModelView should be implemented something like this:


class ModelView(object):
def __init__(self, request, *args, **kwargs):
super(ModelView, self).__init__(request, *args, **kwargs)
# handle url configuration
# handle Meta-class information (maybe this should be in
__new__ or ...)
# etcetera

@requesthandler
def add(self, request, *args, **kwargs):
...

@requesthandler
def edit(self):
...

@requesthandler
def list(self):
...

def page(self):
# doesn't handle requests
...


The urls.py-file used by this class should probably be interpreted a
bit differently, I'm thinking of something like this:


(r'^add/', self.add),
(r'^edit/', self.edit),
(r'^list/', self.list),


The requesthandler should be something like this:


def requesthandler(method):
# make a method that handles the request (currying)...
def new_method(self):
def actual_handler(request, *args, **kwargs):
return method(self, request, *args, **kwargs):
return actual_handler

# ... and make it a property, so it can be decorated
result = property(new_method)

# ... it can be marked to be a request handler, or put in a
list of request handlers, or...
result.is_request_handler = True

return result


Anybody likes the idea? There are a few remarks I'd already like to
make:
- I'm not sure 'ModelView' is the right name for this, since not the
class itself but its requesthandler properties are the actual views.
On the other hand, the name is too nice not to be used.
- I'm no fan of 'class Meta' myself, but I've chosen it here to be
compatible with ModelForm


Cheers, Roald

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



Re: Class based generic views in 1.3?

2010-07-12 Thread Roald
On 17 jun, 22:45, Jacob Kaplan-Moss  wrote:
> Okay, folks: at this point the discussion has pretty much descended
> into bikeshedding territory.

This is no bikeshedding territory, but a new idea.

I just started a new thread on this list, 'ModelView'. It's very
similar to class based generic views; I don't know if it should
actually replace them, or that it's more of a special-case thing (I
think the first). The requesthandler decorator, I think, is relevant
to this thread in either case.

Looking forward to your opinions!

Cheers, Roald

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



load template tag library

2011-11-16 Thread Roald
Hi all,

Can anybody explain why template tag libraries are loaded from
*inside* a template? The more I work with them, the more I get the
feeling that specifying which template tags are available in a
template should be specified in the view-code (or more general: the
thing that loads/renders the template). Why would I, as a back-end
developer, make *all* of my template tags available to the front-end
developer in *all* templates?

A great benefit of moving the template tag library loading to code,
would be that the template language could also be safely used in
CharFields/TextFields, without the risk of users using unwanted
template tags.

Of course, for backward compatibility, this can't be changed. The
thing I'm most interested in, though, is restricting the template tag
libraries that can be used in a template from my view-code. This can
be done in a backward compatible way.

Opinions?

Cheers, Roald

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



Re: load template tag library

2011-11-16 Thread Roald

On Nov 16, 8:40 pm, ptone  wrote:
> On Nov 16, 1:12 am, Roald  wrote:
>
> > Hi all,
>
> > Can anybody explain why template tag libraries are loaded from
> > *inside* a template? The more I work with them, the more I get the
> > feeling that specifying which template tags are available in a
> > template should be specified in the view-code (or more general: the
> > thing that loads/renders the template).
>
> Such as a TemplateEngine...?

Yes, exactly! So what would be the procedure for proposing this? Use
the mailing list, or adding it to the ticket?

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



Re: load template tag library

2011-11-17 Thread Roald
On Nov 17, 12:05 am, Luke Plant  wrote:
> From my perspective, putting the template tag libraries in the view is
> absolutely the wrong thing to do, for a number of reasons:
>
> 1) If I'm reading a template and come across a template tag I don't
> understand, I have to go and find the view it is called from to work out
> what template tag library it might be from. The information is much
> better off in the template.

I agree, hadn't given much thought to readability

> 2) A single template might be used by multiple views. If views are
> responsible for setting the libraries available, they now have duplicate
> content.

I agree that we should avoid code duplication. But I think that that
doesn't have to be the reason to load template tag libraries from the
templates. It could make sense to turn the (html-) template into a
python object in one place (maybe /templates.py), and use this
python object in your views. Then the libraries could be set in this
file (/templates.py).

> 3) If it was done this way, then the available libraries would have to
> be inherited by included templates, and templates that are 'extended
> from'. This makes things even worse for chasing down which template tag
> libraries are in use, especially as a single template can be included
> from multiple places. If you add in the fact that a tag from custom
> template tag library can shadow a builtin, and the deliberate mechanism
> we have for choosing a new version ({% load url from future %}), things
> are getting pretty diabolical.

Agreed

> Template tags essentially form part of the syntax of the template, and
> putting that information outside the template really doesn't make sense.

I don't really see this point. Along this line of thinking you could
also say that defining template tags should be done inside of
templates. Before you know you have recreated PHP ;-).

> As for the need to limit which libraries are allowed for a template, my
> solution would be to do this:
>
> {% load foo bar baz %} {# No others allowed for this template #}
>
> Front-end developers are on the same team. If they refuse to follow
> instructions like that, you should sack them.

I'm not in the position to, so that's not really an option ;-).

> You shouldn't be using the template system in situations where you have
> people who are not trusted, because it simply does not have the security
> necessary for it to be made available to potentially malicious users. It
> was never designed with that in mind, and would probably have dozens of
> major security flaws if you use it in that way. (The protection that
> exists against use of unsafe methods being called is protection against
> *accidental* use of those methods, not against malicious users).
>
> So, if this feature request (restricting the available template tag
> libraries) is part of a security feature, I'm -1 on it, because it
> implies an existing level of security in the template system that
> doesn't exist. To put it another way, if your use case is "allow end
> users to use the template system safely", this feature wouldn't come
> close to doing that. If your use case is "stop front-end developers
> deliberately doing naughty things", I'd say the solution can't be a
> technical one.

OK

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



Re: load template tag library

2011-11-17 Thread Roald

On Nov 17, 8:02 am, Stephen Burrows 
wrote:
> I second what Luke and Russ have already said.
>
> If what you're interested in is a way to securely allow users to enter
> template code into the database, you can just write a custom field
> that validates its input for security problems.
>
> Here's a third-party implementation of a validator for such a 
> field:https://github.com/ithinksw/philo/blob/master/philo/validators.py#L106
>
> This particular implementation:
>
> - lets you explicitly allow particular tags (in which case all other
> tags are disallowed for the field)
> - lets you explicitly disallow particular tags (in which case all
> other tags are allowed for the field)
> - disallows the load, extends, include, and debug template tags by
> default, but lets the backend developer specify the field as
> "insecure" if they want to.
>
> My point being - if what you want is to let people specify template
> code in database fields, there are ways to make it secure without
> rewriting the template engine.

Interesting link! Thanks.

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



Re: #6735 -- Class based generic views: call for comment

2010-10-13 Thread Roald de Vries

Hi Ben,

I like your implementation, but I don't really like the class name  
'View'; I would opt for 'Resource' (or 'ResourceHandle').


Why I don't like 'View':
- It's a very abstract thing, it's conceptually defined as 'the thing  
that maps a request to a response', or something alike

- Instances of the class aren't actually views as they aren't callable
- Consider 'MyView.as_view(*args, **kwargs)', which is weird

Why I like 'Resource':
- A resource is conceptually much clearer than a view (IMHO)
- It conforms to standard naming: a URL addresses a resource
- Methods like 'GET', 'POST', 'PUT', 'DELETE' make sense as attributes  
of a resource (handle)

- django.resources is shorter than django.class_based_views ;-)

I hope this makes sense, please let me know if it doesn't.

Cheers, Roald


On Oct 5, 2010, at 6:33 PM, Ben Firshman wrote:
Thanks to everyone who's helping push this forward. I would get  
stuck in, but I'm bogged down with work at the moment.


A couple of things from the wiki page that need doing:

1) Test coverage probably isn't great. Everything seems to work when  
I've used it in applications, but there's probably some stuff in  
there that isn't thoroughly tested.


2) Support for ModelForms isn't quite the same as our current  
generic views. For edit views, you can specify a model and the form  
is optional.


Ben


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



Feature request: ForeignKey through parameter

2010-10-28 Thread Roald de Vries

Dear all,


I quite often reference foreign keys of foreign keys of foreign  
keys... Wouldn't it be nice to have a 'through'-parameter for  
ForeignKey's?



class A(Model):
b = ForeignKey('B')
c = ForeignKey('C', through='B', related_name='a_set')

class B(Model):
c = ForeignKey('C')


The advantages of a field A.c wrt a property A.c:
- it creates a reverse relation, so C.a_set becomes available
- c becomes queryable: A.objects.filter(c=x)


For 'through'-ing one more class you could use:

class Z(Model):
a = ForeignKey('A')
c = ForeignKey('C', through='A') # works because A.c exists

or:

class Z(Model):
a = ForeignKey('A')
c = ForeignKey('C', through='A__B')  # works regardless of  
whether A.c exists



I'm curious if other people would be interested in such a feature, or  
maybe if something alike or better already exists, and whether there  
are downsides that I miss.


Cheers, Roald

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



Re: Feature request: ForeignKey through parameter

2010-10-28 Thread Roald de Vries

On Oct 28, 2010, at 4:02 PM, Javier Guerra Giraldez wrote:
On Thu, Oct 28, 2010 at 2:54 AM, Roald de Vries   
wrote:
I quite often reference foreign keys of foreign keys of foreign  
keys...

Wouldn't it be nice to have a 'through'-parameter for ForeignKey's?


   class A(Model):
   b = ForeignKey('B')
   c = ForeignKey('C', through='B', related_name='a_set')

   class B(Model):
   c = ForeignKey('C')


i'd love such a feature too, but i think a better syntax could be
something like:

  class A(Model):
  b = ForeignKey('B')
  c = ForeignKey('B__c', related_name='a_set')

  class B(Model):
  c = ForeignKey('C')

where the second part of the reference is the name of the field ('c'
in this example), not the model class ('C')


On first sight, I think I agree with you that the syntax is cleaner  
like this, but I would choose for the through-parameter because it's  
more consistent with the use of the through-parameter for  
ManyToManyField.


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



ForeignKey with null=True

2010-12-16 Thread Roald de Vries

Dear all,


I have a model with a foreign key with null=True:

class Many(Model):
ForeignKey(One, null=True)

class One(Model):
pass

Now if I do:

one = One()

... then:

one.many_set.all()

... returns all Many's with 'self.one_id == None'.

From an implementational (SQL) standpoint, this seems logical, but  
from an OO standpoint, it surely doesn't. I would expect an empty  
queryset as a result, or maybe even some exception. Is the current  
behavior a (conscious) choice/feature, or a bug?



Cheers, Roald

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



Re: RFC: Templatetag API for form rendering - Second Edition

2011-06-10 Thread Roald de Vries

Hi Gregor,

On the way home from DjangoCon I realized there is a (IMHO) elegant  
solution to this problem that is closer to the nature of django's  
template language.


What you want with form-rendering is having defaults, but being able  
to override them; which is something you can do with django's  
templates. I think something like the following would be conceptually  
nice:


# in some template
{% with my_form as form %}
  {% include 'my_app/my_form.html' %}
{% endwith %}

# in templates/my_app/my_form.html
{% extends 'form_as_table.html' %}
{% block fieldblock %}
  {% ifequal field.name 'unnecessary_field' %}
{# don't use this field #}
  {% else %}
{{ block.super }}
  {% endifequal %}
{% endblock %}

# in templates/form_as_table.html
{% block form %}
  {% block formerrors %}
...{# formerrors rendered #}
  {% endblock %}
  {% block fields %}
{% for field in form.fields %}
  {% block field %}

  {% block label %}...{# label rendered #}{% endblock  
%}

  
{% block fielderrors %}...{# fielderrors rendered #} 
{% endblock %}
{% block widget %}...{# widged rendered #}{% endblock  
%}

  

  {% endblock %}
{% endfor %}
  {% endblock %}
{% endblock %}

Now this is not ideal in a few ways; as far as I can see:
1) the form rendering has to be done in a separate file, because  
inheritance is needed

2) it would be more elegant if every field-block would have its own name

Django's template language could be extended a little bit (?) to  
improve this:
1) block inheritance -- like a template can extend another template, a  
block could be able to extend another block or template:

{% block form %}
  {% extends 'partial.html' %}{# or extendsblock block.super #}
{% endblock form %}
2) dynamic block names -- like a template name in an {% extends %} tag  
can be either a string or a variable, the same could hold for the  
block name in a {% block %} tag (backward compatibility would have to  
be solved somehow; different tag name/extra argument/...).


This would result in something like (for removing a field):

{% with my_form as form %}
  {% block form %}
{% extends 'form_as_table.html' %}
{% dynamically_named_block 'unnecessary_field' %}
  {# overrides the field with nothing #}
{% enddynamically_named_block %}
  {% endblock %}
{% endwith %}

Note that also the unnecessary_field-block can extend its base block.

Choosing exactly which fields to render could be done like this:

{% with my_form as form %}
  {% block form %}
{% extends 'form_as_table.html' %}
{% block fields %}
  {% for field_name in 'field1 field2 field3'|split %}
{% dynamically_named_block field_name %}
  {{ block.super }}{# refers to the  
dynamically_named_block #}

{% enddynamically_named_block %}
  {% endfor %}
{% endblock fields %}
  {% endblock %}
{% endwith %}

Just brainstorming... let me know what you think.

Cheers, Roald


On Jun 3, 2011, at 4:58 PM, Gregor Müllegger wrote:


Hi,

this is the second RFC regarding template form rendering API/syntax.  
The first
one defined how a complete form or a subset of fields will be  
rendered. I'm
now proposing more tags to render more details like only the label  
of a form

field.

Currently we haven't discussed how we will substitute what we  
currently do

with using::

{{ form.non_field_errors }}
{{ form.errors }}
{{ form.field.errors }}
{{ form.field.help_text }}
{{ form.field.label_tag }}


We will implement these with template tags that are aware of the  
currently

used layout:

Substituting {{ \*.errors }}::

{% formerrors   
%}


Some examples:
Display *all* errors of a form::
{% formerrors my_form %} (equals current {{ my_form.errors }})

Non-field errors::
{% formerrors my_form.non_field_errors %} equals  
{{ my_form.non_field_errors }}


Single-field errors::
{% formerrors my_form.firstname %} equals  
{{ my_form.firstname.errors }}


Basically it will render the error list/dict that is available in  
the *errors*

attribute of the passed in object. As an alternative (e.g. the
non_field_errors) you can pass in directly a error list that gets  
rendered::


{% formerrors my_custom_error_list %}
{% formerrors my_form.field.errors %}


Substituting ``{{ form.field.label_tag }}``

This one might be pretty obvious::
{% formlabel my_form.field %}


Substituting {{ form.field.help_text }}

Also pretty obvious::
{% formhelp my_form.field %}

But the naming is IMO not ideal. {% helptext %} as alternative is  
reasonable,
but Carl and I agreed on that we wanted the tag to start with form*  
but

{% formhelptext %} is t

Re: class based views: object instead of dictionary as context?

2011-09-15 Thread Roald de Vries


On Sep 13, 2011, at 9:28 PM, Reinout van Rees wrote:


On 13-09-11 20:33, Tobias McNulty wrote:

   I love it when problems solve themselves :-)


That's a good point.  Are there *any* methods in the CBVs that don't
take arguments, that also modify data?  The only one that I found  
in the

list I'd initially proposed that can be called without arguments is
as_view(), and I'm not sure that really even needs protection.  Maybe
there's no need to protect anything with alters_data / proxying?


There's not really anything useful you can do with as_view in your  
template, should you attempt it. I also don't think you can do  
anything destructive with it.


as_view() is a classonlymethod, which gives an AttributeError when  
called on an instance, so putting an instance of the cbv in the  
context seems fine for as far as this 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 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.



Re: RFC: "universal" view decorators

2011-09-16 Thread Roald de Vries

Hi,

On Sep 16, 2011, at 12:11 AM, Łukasz Rekucki wrote:


Hi,

On 15 September 2011 22:44, Jacob Kaplan-Moss   
wrote:


#14512 proposes a adding another view-decorator-factory for  
decorating

class-based views, which would turn the above into::

   @class_view_decorator(login_required)
   class MyView(View):
   ...

This makes me less sad, but still sad. Factory functions. Ugh.


As the ticket creator I feel obligated to reply :)


Me (as the poster of the latest patch) too :)


Thinking about it now, it does look kinda ugly. It's mainly because I
was focus on how to reuse existing decorators in CBV context. It
shouldn't be to hard  to make the "view_decorator" a meta-decorator
(or a factory function as you call it) that turns login_required to
something that is both a class and function decorator. Methods are
still out-of-bounds for non-runtime introspection, but after almost 1
year of using CBV, I never needed to decorate a method.

I would like to also comment on the new approach in that ticket.
Making a shallow copy of a class is *MAGIC* to me. It breaks the basic
invariant "issubsclass(decorator(A), A) == True". This is important if
you're planing to use this as "B = decorator()(A)" (and you are,
'cause the whole point of not modifying the original class is to allow
safely doing this), as you quickly end up with weird alternate
hierarchies. So, please don't do that :)


I agree that in an ideal world we'd have a better solution. On the  
other hand, the cbv-decorator using inheritance just didn't work, and  
the one using shallow copies does (if you don't use B=decorator()(A),  
indeed).


As Donald mentioned, the more elegant solution for classes is to use  
base classes (mixins) instead of class decorators. I'm not sure though  
if every decorator can be replaced by a mixin, and if the order of  
these mixins can be arbitrary in that case (which I believe is  
desirable). Can anybody comment on that?



I believe, however, I've figured out a different technique to make
this work: don't try to detect bound versus unbound methods, but
instead look for the HttpRequest object. It'll either be args[0] if
the view's a function, or args[1] if the view's a method. This
technique won't work for any old decorator, but it *will* work (I
think) for any decorator *designed to be applied only to views*.


+1 on this. I would be a bit concerned about this vs. future
implementation of generator-based-views that allow some kind of
response streaming (is someone working on that?).


I've written a proof-of-concept patch to @login_required (well,
@user_passes_test, actually):

   https://gist.github.com/1220375


Did I already mention creating a subclass in the class decorator
breaks super ;) [https://gist.github.com/643536]

Can I get some thoughts on this technique and some feedback on  
whether

it's OK to apply to every decorator built into Django?


It would be great to have that meta-decorator, so everyone else could
upgrade their decorators just by decorating them.


If this doesn't exist, then the view_decorator still has a right to  
live.


So what would have to be created is a meta-decorator  
universal_decorator, replacing or using view_decorator, such that  
universal_decorator(login_required) is the actual universal decorator.  
This would be applied to all django-decorators, but I think it would  
be good to also allow applying universal_decorator to an already  
universal decorator, such that:


# after this...
login_required = universal_decorator(login_required)
# ... this will hold
assert login_required == universal_decorator(login_required)







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



Re: RFC: "universal" view decorators

2011-09-16 Thread Roald de Vries

On Sep 16, 2011, at 10:08 AM, Jonathan Slenders wrote:


class ProtectedView(MyView):
   login_required = True

Where 'MyView' checks all the view's options during a dispatch. Never
liked inheritance with multiple base classes...


How would I create my own 'decorators' in this approach?

Cheers, Roald

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



Re: RFC: "universal" view decorators

2011-09-16 Thread Roald de Vries

On Sep 16, 2011, at 11:42 AM, Łukasz Rekucki wrote:


On 16 September 2011 10:17, Roald de Vries  wrote:

On Sep 16, 2011, at 12:11 AM, Łukasz Rekucki wrote:

I would like to also comment on the new approach in that ticket.
Making a shallow copy of a class is *MAGIC* to me. It breaks the  
basic
invariant "issubsclass(decorator(A), A) == True". This is  
important if

you're planing to use this as "B = decorator()(A)" (and you are,
'cause the whole point of not modifying the original class is to  
allow

safely doing this), as you quickly end up with weird alternate
hierarchies. So, please don't do that :)


I agree that in an ideal world we'd have a better solution. On the  
other
hand, the cbv-decorator using inheritance just didn't work, and the  
one
using shallow copies does (if you don't use B=decorator()(A),  
indeed).


The one that just alters the given class also works, has no magic and
has the same limitation - dont' do "B = decorator(A)".


To show that this is actually a Python-thing, an analogous non- 
decorator-example:


>>> class A(Base):
... def method(self, *args, **kwargs):
... super(A, self).method(*args, **kwargs)
...
... B = A
... A = SomeOtherClass
...
... B.method()
Traceback (most recent call last):
...
TypeError: unbound method method() must be called with A instance  
as first argument (got nothing instead)


So IMHO it's "pythonic" to leave responsibility to use the decorator  
in the right way to the programmer.


Cheers, Roald

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



Re: RFC: "universal" view decorators

2011-09-16 Thread Roald de Vries

On Sep 16, 2011, at 6:19 PM, Donald Stufft wrote:

Documentation is being worked on, and is orthogonal to the current  
discussion of how

to handle things like requiring logins with the new CBVs.


I just watched "Class Decorators: Radically Simple" by Jack Diederich,  
who wrote the class decorators PEP, and I think it's very useful to  
watch (25 min.) for this discussion. According to him it is good  
practice to return the class that is decorated, which I think we  
should follow, and which solves the biggest practical problems with  
decorating. Moreover, the fact that class decorators exist indicate  
that they are pythonic. So +1 for the decorators.


Considering the mixins: IMHO, the order of base classes shouldn't  
matter. Can this be satisfied by the mixin-approach?


@Carl Meyer: I would opt for applying decorators *in* the class, so  
you can still derive from it. Like::


class MyView(View):
@classonlymethod
def as_view(cls, *args, **kwargs):
return login_required(super(MyView, cls).as_view(*args,  
**kwargs))


Cheers, Roald

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



ManyRelatedManager with explicit intermediary model

2011-09-20 Thread Roald de Vries

Hi all,

Is there a fundamental reason that I'm missing (other than "nobody's  
taken the trouble of writing it") that I can't do the following? If  
there isn't I'll create a ticket for it.


class R(Model):
user = ForeignKey(User)
my_model = ForeignKey('MyModel')
comment = CharField(max_length=100, blank=True)

class MyModel(Model):
users = ManyToManyField(User, through=R, null=True)

m = MyModel.objects.create()
u = User.objects.create_user('roald', 'downa...@gmail.com',  
'password')



# these things I can't do:
m.users.add(u)
m.users.add(u, comment='Blablabla')

Cheers, Roald

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



Re: ManyRelatedManager with explicit intermediary model

2011-09-20 Thread Roald de Vries

On Sep 20, 2011, at 4:23 PM, Stephan Jaensch wrote:


Am 20.09.2011 um 15:52 schrieb Roald de Vries:

Is there a fundamental reason that I'm missing (other than  
"nobody's taken the trouble of writing it") that I can't do the  
following? If there isn't I'll create a ticket for it.




  class R(Model):
  user = ForeignKey(User)
  my_model = ForeignKey('MyModel')
  comment = CharField(max_length=100, blank=True)

  class MyModel(Model):
  users = ManyToManyField(User, through=R, null=True)

  m = MyModel.objects.create()
  u = User.objects.create_user('roald', 'downa...@gmail.com',  
'password')



  # these things I can't do:
  m.users.add(u)
  m.users.add(u, comment='Blablabla')


https://docs.djangoproject.com/en/1.3/topics/db/models/#intermediary- 
manytomany


You can't use add() when specifying the intermediate model. You  
would have to check all fields of the intermediate model and make  
sure all of them have defaults or are allowed to be null. It might  
not be worth the trouble of implementing it.


I don't see how this is different from the create method on the  
intermediary model.


Cheers, Roald

PS: I found an open ticket on this, https://code.djangoproject.com/ticket/9475

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



Re: ManyRelatedManager with explicit intermediary model

2011-09-21 Thread Roald de Vries


On Sep 20, 2011, at 5:50 PM, Tom Evans wrote:

On Tue, Sep 20, 2011 at 4:12 PM, Roald de Vries   
wrote:


I don't see how this is different from the create method on the  
intermediary

model.

Cheers, Roald

PS: I found an open ticket on this,
https://code.djangoproject.com/ticket/9475



Here is the function definition for add() on related object manager:

add(obj1[, obj2, ...])

As you can see, it can be used to add multiple objects to the
relationship in one go, and therefore the arguments to this function
would need to change to support what you propose. This would require
going through the whole deprecation procedure (2/3 major releases
before it is gone), and I guess the pain outweighs the gain on that
one.


add(*objs, **kwargs) is backward compatible with add(*objs), so that's  
not the reason a deprecation procedure is needed. The thing that might  
be considered backward incompatible is the fact that with this new  
feature, the 'add' method is also defined on ManyRelatedManagers with  
explicit intermediary models.



create() takes **kwargs, but those arguments relate to the instance
being created on the other end of the relationship, there would still
be no way to specify non-default values for the intermediate model.
You would have to do something similar to passing a defaults
dictionary to create(), which then makes it different to how create()
on an object manager works, and introduces another field that you
would have to do some magic to work around.

I guess the main thing is what's the point? The argument is over which
of these is prettier:

model_a_instance.modelb_set.add(model_b_instance)

and

Intermediate.objects.create(model_a=model_a_instance,  
model_b=model_b_instance)


Beauty contests in code are rather pointless - the documentation has
for a long time said that the latter is the only way you can do it,
and most developers are now used to that.


I don't want to forbid the second form, you may still use it if you  
like it better. For me, it seems more consistent (which I think is  
more beautiful) to create a relation between 2 instances from one of  
the instances, because I always access the other instance through the  
ManyRelatedManager on the one. If there are enough people that like  
the first form, then that's the point.



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



Re: RFC: "universal" view decorators

2011-09-21 Thread Roald de Vries

Hi all,

Haven't seen a comment on this topic for a few days, so was wondering  
if a core dev can make a design decision yet. I have some spare time  
in the remainder of this week, so if the (universal) decorator- 
approach is chosen, I should be able to finish it shortly (the mixin- 
approach is a bit harder to estimate).


Cheers, Roald


On Sep 17, 2011, at 4:32 AM, Alex Gaynor wrote:

On Fri, Sep 16, 2011 at 10:27 PM, Donald Stufft > wrote:
unittest.skip isn't a Mixin, it turns the class into an exception  
and raises it.



It doesn't *turn* a class into anything, it simply returns a  
function, instead of a new class, and the function raises SkipTest,  
the point wasn't the implementation detail, but rather the syntax  
and pattern at work.


django.test.utils.override_settings is a mixin and it's terrible, it  
dynamically creates a new subclass, and overrides 2 methods. It's  
magic and more complex then need be.


a) it's not a mixin
b) yes, it creates subclasses, because the alternative is mutating  
the original class, which isn't how people generally expect  
decorators to work, we expect them to be syntactic sugar for:


A = wrap(*args)(A)

such that we can also do

B = wrap(*args)(A)

and have two classes (or functions).

c) I'm not sure how it's magic, but certainly if it's too complex  
we'd take patches to simplify the implementation.


On Friday, September 16, 2011 at 9:50 PM, Alex Gaynor wrote:




On Fri, Sep 16, 2011 at 9:47 PM, James Bennett  
 wrote:

We have the following constraints:

1. Django supports class-based views.

2. Django supports function-based views (ultimately these are the  
same

thing, which is that Django supports anything as a 'view' so long as
it's callable, accepts an HttpRequest as its first positional  
argument

when being called and either returns an HttpResponse or raises an
exception).

3. The natural way to add processing in/around a class is  
subclassing

and either overriding or mixing in.

4. The natural way to add processing in/around around a function  
is decorating.


Any solution to this needs to address those constraints, and allow
code to look and feel natural.

Based on that, some arrangement which allows the same basic logic to
exist in a "mixin" (I dislike that word) for classes and a decorator
for functions seems most appropriate, even if it does mean having  
two
ways to do things -- that's a distinction I think we can live  
with, as
people will appreciate that it doesn't result in strange-looking  
code.


I agree with all your points, except #3, I think it's an over  
simplification.  There's another way to change a class: class  
decorators.  And there's ample precedent for their use in such a  
manner, unittest's skip decorators, our own decorators for swapping  
settings during testing, etc.


Alex


Alex


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