CurrentUser, Owner permission, and so forth ...

8 views
Skip to first unread message

brice.ca...@gmail.com

unread,
Jan 10, 2006, 7:05:33 PM1/10/06
to Django developers
Hi folks,
Yes, I'm bringing this issue again, please don't throw things at me !

Basically, I would want to open a discussion on these subjects so as to
define a clean solution to this problem, if at least possible.

I think I'm gonna give some use cases that should, in my very humble
opinion, be fulfilled by Django :

- CurrentUser:
In a multi-user content management system (cms), the client sometimes
(well, for every project I've been working on, this has been a client
will, but it might be french-client-specific) want to keep track of the
author, or poster of a document.
The current django state on the subject is to create a ForeignKey on
meta.Users, and have the author to select himself in the list.
This has two drawbacks :
1/ the user has to do something that should be dealt with by the system
(since he is already authentified)
2/ this system allows one to specify another user than him (either on
purpose or by mistake)
One could enforce this by writing custom views, but then you can't use
provide your users with the admin interface
Related tickets : 1132 [1] and 1164 [2]

- Owner user and / or group permission :
This is a somewhat related issue. For a multi-user cms, the client
wants
to be able to define some more granulated permission. For example "only
owner can edit this very document" (now that I think about it, I can't
find any other example not already covered by Django's permission
system, but it's quite late there).

I'm sure solutions have already been provided for both problems
(tickets
1132 and 1164 both provides solutions for the CurrentUser issue), but
as
of now, these solutions have been (in my own opinion rightly) deemed
too
hackish to get committed. This thread is aimed at finding a clean
implementation of those two concepts.
Obviously, the solution _will_ introduce some coupling between the data
layer and the request layer (well, who knows ?). The point is mainly to
make it as light as possible.

I know, I didn't provide any answer right now. But let's brainstorm on
the subject and something might pop and seem simply the right way !

Regards,

[1] http://code.djangoproject.com/ticket/1132
[2] http://code.djangoproject.com/ticket/1164

--
Brice Carpentier aka Br|ce

Joseph Kocherhans

unread,
Jan 10, 2006, 7:26:12 PM1/10/06
to django-d...@googlegroups.com
On 1/10/06, brice.ca...@gmail.com <brice.ca...@gmail.com> wrote:
>
> 1132 and 1164 both provides solutions for the CurrentUser issue), but
> as
> of now, these solutions have been (in my own opinion rightly) deemed
> too
> hackish to get committed. This thread is aimed at finding a clean
> implementation of those two concepts.
> Obviously, the solution _will_ introduce some coupling between the data
> layer and the request layer (well, who knows ?). The point is mainly to
> make it as light as possible.

I wrote both patches. Please just ignore #1132. It sucks. I was pretty
much just trying to start a conversation there with the simplest (in
this case least amount of code) thing I could get to work. (I probably
should have done so on the list) #1164 is better IMHO, but I still
don't like it too much. I got the context processor ideas from
rjwittams. I think he's still on vacation, but I'd love to hear how
close I came to what he was imagining.

What do people think about the context processor idea? Not necessarily
this implementation, but just the idea of a generic context (just a
dict in the simplest case) that gets passed in to the manipulator for
access by fields. AFAICT this is where the "coupling" is happening.
Any other ideas on how a field might get access to the current user?

Joseph

Brice Carpentier

unread,
Jan 11, 2006, 4:14:03 AM1/11/06
to Django developers
2006/1/11, brice.ca...@gmail.com <brice.ca...@gmail.com>:

> Hi folks,
> Yes, I'm bringing this issue again, please don't throw things at me !
>
> Basically, I would want to open a discussion on these subjects so as to
> define a clean solution to this problem, if at least possible.
>
> I think I'm gonna give some use cases that should, in my very humble
> opinion, be fulfilled by Django :
>
> - CurrentUser:
> In a multi-user content management system (cms), the client sometimes
> (well, for every project I've been working on, this has been a client
> will, but it might be french-client-specific) want to keep track of the
> author, or poster of a document.
> The current django state on the subject is to create a ForeignKey on
> meta.Users, and have the author to select himself in the list.
> This has two drawbacks :
> 1/ the user has to do something that should be dealt with by the system
> (since he is already authentified)
> 2/ this system allows one to specify another user than him (either on
> purpose or by mistake)
> One could enforce this by writing custom views, but then you can't use
> provide your users with the admin interface
> Related tickets : 1132 [1] and 1164 [2]
>
I was thinking that this has nothing to do in the model. So maybe this
should be done in the controller, in our case by the admin site. So
*maybe* a solution would to be able to say something like this :

author = meta.ForeignKey(meta.User)

[...]

admin=Admin(
[...]
fill_with_current_user=('author',)
)

This would allow us to write the directive in the model file, but have
it executed in the controller.
This is somehow inconsistent with the way auto_now and auto_now_add
are used, but these don't depend on the request object.

Any feeling about this anyone ?

Brice Carpentier

unread,
Jan 11, 2006, 4:26:02 AM1/11/06
to django-d...@googlegroups.com
2006/1/11, Joseph Kocherhans <jkoch...@gmail.com>:

> I wrote both patches. Please just ignore #1132. It sucks. I was pretty
> much just trying to start a conversation there with the simplest (in
> this case least amount of code) thing I could get to work. (I probably
> should have done so on the list) #1164 is better IMHO, but I still
> don't like it too much. I got the context processor ideas from
> rjwittams. I think he's still on vacation, but I'd love to hear how
> close I came to what he was imagining.
>
Okay, let's forget #1132 then, and hurra to #1164 :)
Yup, having a feedback from robert would be interesting. I'd also like
to have adrian's opinion.

> What do people think about the context processor idea? Not necessarily
> this implementation, but just the idea of a generic context (just a
> dict in the simplest case) that gets passed in to the manipulator for
> access by fields. AFAICT this is where the "coupling" is happening.
> Any other ideas on how a field might get access to the current user?
>

I don't know. It is certainly practical, but I fear it might be, I
don't know ... too easy ... and that would allow weird things. I mean,
shouldn't those things be done in the controller ?

Regards,

Joseph Kocherhans

unread,
Jan 11, 2006, 11:31:48 AM1/11/06
to django-d...@googlegroups.com

I think that's pretty much what people are worried about. Hmm... quick
idea (this just occured to me) I'm assuming the magic-removal branch
here.

Create a ForeignKey field that references
django.contrib.auth.models.User or whatever. This field cannot be
editable=False, or the manipulator will skip over it when you save the
object. Exclude the field from your admin screens using the fields
attribute of the new inner Admin class. At this point, the user field
is techincally editable, but not displayed. Then, the admin add/change
views (controller in your terminology) call a method of the inner
Admin class to set the correct user in new_data or something before
the manipulator validates and saves it. The details obviously need to
be worked out, but I think this is a pretty clean solution. Nothing
changes but admin views, and the inner Admin class. No more coupling.

Thoughts?
Joseph

Brice Carpentier

unread,
Jan 11, 2006, 12:03:36 PM1/11/06
to django-d...@googlegroups.com
2006/1/11, Joseph Kocherhans <jkoch...@gmail.com>:

> Create a ForeignKey field that references
> django.contrib.auth.models.User or whatever. This field cannot be
> editable=False, or the manipulator will skip over it when you save the
> object. Exclude the field from your admin screens using the fields
> attribute of the new inner Admin class. At this point, the user field
> is techincally editable, but not displayed. Then, the admin add/change
> views (controller in your terminology) call a method of the inner
> Admin class to set the correct user in new_data or something before
> the manipulator validates and saves it. The details obviously need to
> be worked out, but I think this is a pretty clean solution. Nothing
> changes but admin views, and the inner Admin class. No more coupling.
>
I kinda like it.

Adrian Holovaty

unread,
Jan 11, 2006, 12:14:35 PM1/11/06
to django-d...@googlegroups.com
On 1/11/06, Joseph Kocherhans <jkoch...@gmail.com> wrote:
> Create a ForeignKey field that references
> django.contrib.auth.models.User or whatever. This field cannot be
> editable=False, or the manipulator will skip over it when you save the
> object. Exclude the field from your admin screens using the fields
> attribute of the new inner Admin class. At this point, the user field
> is techincally editable, but not displayed. Then, the admin add/change
> views (controller in your terminology) call a method of the inner
> Admin class to set the correct user in new_data or something before
> the manipulator validates and saves it. The details obviously need to
> be worked out, but I think this is a pretty clean solution. Nothing
> changes but admin views, and the inner Admin class. No more coupling.

Oooh, I like this. Putting methods in the inner Admin class is very clean.

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com | chicagocrime.org

Brice Carpentier

unread,
Jan 11, 2006, 12:18:20 PM1/11/06
to django-d...@googlegroups.com
2006/1/11, Adrian Holovaty <holo...@gmail.com>:

> Oooh, I like this. Putting methods in the inner Admin class is very clean.
>
\o/

Joseph Kocherhans

unread,
Jan 11, 2006, 12:19:19 PM1/11/06
to django-d...@googlegroups.com

I'll work this up after the namespace stuff is done. magic-removal has
been a branch for too long ;) If the manipulators and descriptor field
changes haven't been finished, maybe this and my other proposal for
redirects can go on the brach too, but first things first. :)

Joseph

Maniac

unread,
Jan 11, 2006, 1:38:53 PM1/11/06
to django-d...@googlegroups.com
Joseph Kocherhans wrote:

>Create a ForeignKey field that references
>django.contrib.auth.models.User or whatever. This field cannot be
>editable=False, or the manipulator will skip over it when you save the
>object. Exclude the field from your admin screens using the fields
>attribute of the new inner Admin class. At this point, the user field
>is techincally editable, but not displayed. Then, the admin add/change
>views (controller in your terminology) call a method of the inner
>Admin class to set the correct user in new_data or something before
>the manipulator validates and saves it. The details obviously need to
>be worked out, but I think this is a pretty clean solution. Nothing
>changes but admin views, and the inner Admin class. No more coupling.
>
>

This will work only in Admin but authentication generally isn't tied to
it. I recall that people in django-users were interested in automatic
user assignment to work in any view and they didn't want to insert
"SomeModel.created_by=request.user" in every view. It's expected to work
just like auto_now fields.

My first thought were that instead of

new_data=request.POST.copy()

we could do

new_data=request.get_post_data()

which would return a dict-like object but also with attribute "user" set
to "request.user". The manipulator then may use it to populated
"auto_created_by" and "auto_changed_by" fields.

But now I don't like it either since it ties core to Auth which is
optional. Thoughts?

Joseph Kocherhans

unread,
Jan 11, 2006, 2:09:36 PM1/11/06
to django-d...@googlegroups.com

I don't like get_post_data() as a method of request. I think it would
would be cleaner if it was a method if the inner Meta (or posibly
inner Admin) class. In that case, Meta.get_post_data() *could* ask all
the fields to modify new_data, kind of like the context processors in
ticket #1164.

Something like a display=False/True attribute for fields in addition
to editable=False/True would be convenient here, as often times you'll
want to display all but one or two fields.

What would really be nice is callable defaults that can also update
new_data. It would take care of the auto_add/auto_add_now stuff as
well. auto_add/auto_add_now and auto_created_by/auto_changed_by could
be handled with a callable default and a new allow_updates=True/False
(or something) attribute on fields. auto_add/auto_add_now could
disappear then.

Joseph

Adrian Holovaty

unread,
Jan 11, 2006, 4:46:51 PM1/11/06
to django-d...@googlegroups.com
On 1/11/06, Maniac <Man...@softwaremaniacs.org> wrote:
> This will work only in Admin but authentication generally isn't tied to
> it. I recall that people in django-users were interested in automatic
> user assignment to work in any view and they didn't want to insert
> "SomeModel.created_by=request.user" in every view. It's expected to work
> just like auto_now fields.

I don't see a need to add this functionality for use beyond the scope
of the admin site. The auto_now options aren't coupled to a request,
so they're a special case. Coupling a request's user object to
manipulators is something we shouldn't do. The proposed solution of
encapsulating it in the "class Admin" is nice and clean.

Joseph Kocherhans

unread,
Jan 11, 2006, 5:12:05 PM1/11/06
to django-d...@googlegroups.com
On 1/11/06, Adrian Holovaty <holo...@gmail.com> wrote:
>
> On 1/11/06, Maniac <Man...@softwaremaniacs.org> wrote:
> > This will work only in Admin but authentication generally isn't tied to
> > it. I recall that people in django-users were interested in automatic
> > user assignment to work in any view and they didn't want to insert
> > "SomeModel.created_by=request.user" in every view. It's expected to work
> > just like auto_now fields.
>
> I don't see a need to add this functionality for use beyond the scope
> of the admin site. The auto_now options aren't coupled to a request,
> so they're a special case. Coupling a request's user object to
> manipulators is something we shouldn't do. The proposed solution of
> encapsulating it in the "class Admin" is nice and clean.

I would like to see this in the generic views as well (in which case
maybe the method should be in Meta?). Other than that, people need to
use custom views anyhow, so they can do what they need to there.

Joseph

Robert Wittams

unread,
Jan 11, 2006, 6:14:55 PM1/11/06
to django-d...@googlegroups.com

Ok, back, kind of caught up - not entirely though.

Erk. I really don't like the idea of this "shove all vaguely complex
behaviour into the admin" way of going about things. The aim should be
for the admin to be a totally bog standard django app with not too much
special going on. The only reason that we can "get away" with not
passing in a request for auto_now etc is that the time is an implicitly
globally accessible bit of state. This is not always to be considered a
benefit ( referential transparency and covert channel issues).

We do need some general way to encapsulate extracting bits of
information from a request to populate/modify a field - and not repeat
ourselves in views - ie it needs to be doable in generic views. By this
I don't mean "shove the same hacks in the admin and the generic views" ,
but that if a view is written in a fairly oblivious fashion, it should
just work.

We can shout "coupling is bad" until we are blue in the face : the fact
remains that this is a problem that a very large number of people are
having (and no - it certainly isn't limited to the admin), we shouldn't
sweep it under the carpet by hackishly solving it in the admin and
hoping that people will cut and paste it into their views...

The phrase "special case" should make us cringe - most of the time its a
sure sign you are doing something wrong.

Maniac

unread,
Jan 11, 2006, 6:50:48 PM1/11/06
to django-d...@googlegroups.com
Adrian Holovaty wrote:

>I don't see a need to add this functionality for use beyond the scope
>of the admin site.
>

Well... I can recall more than one request in django-users :-). And this
feature is pretty commonplace...

> The auto_now options aren't coupled to a request,
>so they're a special case. Coupling a request's user object to
>manipulators is something we shouldn't do.
>

In fact I was thinking in the lines of decoupling authenticated user
from a request too :-). It can be in request.user too but this
functionality could work like this:

- auth app using event system hooks to the save event for models
- auth middleware populates request.user and also keeps the user for
itself in some warm private place
- on model's save it looks in its Meta for fields that should be
populated and does it

Thus all the functionality is kept in one app. I didn't look into
anything concerning event system but from reading this list I got an
impression that it suits naturally for this kind of things.

Maniac

unread,
Jan 11, 2006, 6:55:10 PM1/11/06
to django-d...@googlegroups.com
Maniac wrote:

> - auth app using event system hooks to the save event for models
> - auth middleware populates request.user and also keeps the user for
> itself in some warm private place
> - on model's save it looks in its Meta for fields that should be
> populated and does it

Wait, there's more! :-)

In addition to populating private var from middleware auth app can have
some public method to do authentication. And thus work in a totally
non-web environment. It can even require authentication by preventing
model's save if there's no currently authenticated user.

I kinda want to write such a thing if there are no serious objections
and when event system is ready.

Adrian Holovaty

unread,
Jan 11, 2006, 9:30:57 PM1/11/06
to django-d...@googlegroups.com
On 1/11/06, Maniac <Man...@softwaremaniacs.org> wrote:
> I kinda want to write such a thing if there are no serious objections
> and when event system is ready.

You can get started, if you're willing to use the magic-removal branch. :)

The event system is in that branch, in django.dispatch.

Maniac

unread,
Jan 11, 2006, 9:40:00 PM1/11/06
to django-d...@googlegroups.com
Adrian Holovaty wrote:

>You can get started, if you're willing to use the magic-removal branch. :)
>
>The event system is in that branch, in django.dispatch.
>
>

Ok. I'll get to it as soon as I could kill some more lines from ToDo on
my desktop :-)

Joseph Kocherhans

unread,
Jan 23, 2006, 3:27:15 PM1/23/06
to django-d...@googlegroups.com
On 1/11/06, Maniac <Man...@softwaremaniacs.org> wrote:
>

Have you started on this yet maniac? Were you going to use
threading.local() (or something similar) to store the user, or did you
have something else in mind? I've got a hack that uses a thread local,
middleware, and a custom Field (using it's get_default method) to save
the current user. I can help get this started if you want.

Joseph

Maniac

unread,
Jan 23, 2006, 3:52:41 PM1/23/06
to django-d...@googlegroups.com
Joseph Kocherhans wrote:

>Have you started on this yet maniac?
>

Not yet. And actually can't predict when I'll be able to :-(. So feel
free to implement the idea if you like. Please post here a ticket number
to track the thing.

Joseph Kocherhans

unread,
Jan 23, 2006, 5:48:50 PM1/23/06
to django-d...@googlegroups.com

I've added a naive patch/ticket to track this. It only takes care of
user storage right now, and I'm unsure of how this would perform under
load, but here it is:

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

Joseph

Simon Greener

unread,
Jan 23, 2006, 6:07:36 PM1/23/06
to django-d...@googlegroups.com
Folks,

Dunno if this is the right place to ask this question but I
would like to get a copy of all the Django documentation as
a single download and not have to go to the actual Django site.
Does the documentation exist as a single download?

I have been looking for an MDA framework for a multi-table data model
I currently have documented in a data modelling case tool. I have that
data model in MySQL and am slowly looking into how to Django-enable it.
I first tried reverse engineering the MySQL model into Django but was
not happy with the result - probably because I still don't understand
Django well enough. Then, because the CASE tool I use allows for user
scripting, I decided to go from what I know (the model) to Django so
I wrote a new script that generate Django models. My initial scripts are
producing Django models that "django-admin.py sql ..." then turns into
MySQL
SQL that are almost identical to my original model-driven SQL (both for
Oracle
and for MySQL)! This "test" has given me great hope and now I am
considering
deleting all the "physical" model artifices in my original model and
returning
it to a standard logical model and let Django generate the physical model
eg
I model the many-to-many intersection table myself even though it does not
contain
any other attributes than the keys.

I am taking this approach as this is one of the best ways of learning any
new framework
or language - apply it to something concrete that needs to be done. But
there is so
much to learn especially for someone who does not know anything about
Python which is
why I have asked about single documentation downloads. I do not always
have access to
the internet (I am a consultant who is often on the road).

regards
Simon
--
SpatialDB Advice, Solutions Architect, Oracle Spatial Specialist.
Allens Rivulet, Tasmania, Australia.
Voice: +61 3 62396397
Longitude: 147.2048
Latitude: -43.0141

Adrian Holovaty

unread,
Jan 23, 2006, 6:11:01 PM1/23/06
to django-d...@googlegroups.com
On 1/23/06, Simon Greener <sgre...@netspace.net.au> wrote:
> Dunno if this is the right place to ask this question but I
> would like to get a copy of all the Django documentation as
> a single download and not have to go to the actual Django site.
> Does the documentation exist as a single download?

Hey Simon,

The docs are all available in the "docs/" directory in the Django
tarball. They're in ReST (restructured text) format. The docs on the
Django site are generated from those ReST documents, so you can be
confident the content is the same. (The only difference is that we
make lots of improvements to documentation, and the current docs on
the Django site reflect the latest improvements, which you can get
from Django's subversion repository.)

Thanks for using Django!

Simon Greener

unread,
Jan 23, 2006, 6:22:28 PM1/23/06
to django-d...@googlegroups.com
Adrian,

> On 1/23/06, Simon Greener <sgre...@netspace.net.au> wrote:
>> Dunno if this is the right place to ask this question but I
>> would like to get a copy of all the Django documentation as
>> a single download and not have to go to the actual Django site.
>> Does the documentation exist as a single download?
>
> Hey Simon,
>
> The docs are all available in the "docs/" directory in the Django
> tarball. They're in ReST (restructured text) format. The docs on the
> Django site are generated from those ReST documents, so you can be
> confident the content is the same. (The only difference is that we
> make lots of improvements to documentation, and the current docs on
> the Django site reflect the latest improvements, which you can get
> from Django's subversion repository.)

OK, thanks for confirming this for me. I had seen the docs but simply
didn't know their relationship to those on the site. Anyway, the ones on
the site are easier to read which is why I asked if they could be
downloaded
all in one hit rather than having to File>Save As (as I have done for
previous ones).

This is how much of a neophyte I am: what is a "subversion repository"?
(And I am
a pretty technical sort of a guy - though more a solutions architect and
database
designer in the area of digital mapping than "down in the bowels"
programming.)

regards
S.

Adrian Holovaty

unread,
Jan 23, 2006, 6:29:39 PM1/23/06
to django-d...@googlegroups.com
On 1/23/06, Simon Greener <sgre...@netspace.net.au> wrote:
> OK, thanks for confirming this for me. I had seen the docs but simply
> didn't know their relationship to those on the site. Anyway, the ones on
> the site are easier to read which is why I asked if they could be
> downloaded
> all in one hit rather than having to File>Save As (as I have done for
> previous ones).

No problem. I've added your question to the FAQ so it helps others in
the future.

http://www.djangoproject.com/documentation/faq/#how-can-i-download-the-django-documentation-to-read-it-offline

> This is how much of a neophyte I am: what is a "subversion repository"?

It's the source-code repository; it's the system that keeps track of
changes to our code, so we can roll back to previous versions and see
how files have changed over time. (Another commonly-used source-code
repository is CVS, which you may have heard of.) Some folks like to
use the "bleeding-edge" Django code by using the development version,
which means they get the benefit of code improvements as soon as
they're added, rather than having to wait for "releases" of Django.
Hope that clears things up a bit!

Max Battcher

unread,
Jan 24, 2006, 12:46:23 AM1/24/06
to django-d...@googlegroups.com
Simon Greener wrote:
> OK, thanks for confirming this for me. I had seen the docs but simply
> didn't know their relationship to those on the site. Anyway, the ones on
> the site are easier to read which is why I asked if they could be
> downloaded
> all in one hit rather than having to File>Save As (as I have done for
> previous ones).

If you want the nice inter-hyperlinked HTML you can download the tools
from http://docutils.sourceforge.net/ and use the command line tool
``buildhtml.py`` included in the package's tools directory.

--
--Max Battcher--
http://www.worldmaker.net/
"History bleeds for tomorrow / for us to realize and never more follow
blind" --Machinae Supremacy, Deus Ex Machinae, Title Track

Reply all
Reply to author
Forward
0 new messages