I am coming up with a framework that helps serialization of models. My
idea is for each field to have a view permissions level: PUBLIC,
OWNER, or ADMIN. I want to have a model to dict function that takes 2
arguments, permission_level and serialize_chain. Firstly, let me
explain how it would change models.py:


from django.db import models
from django.contrib.auth.models import User
class Profile(models.Model):
    user = models.ForeignKey(User, permission=PUBLIC)
    bio = models.TextField(permission=PUBLIC)
    activated = models.BooleanField(default=False, permission=OWNER)
    activate_code = models.CharField(max_length=256, permission=ADMIN)
    pages_bookmarked = models.ManyToManyField('Page',
related_name='profile_pages_bookmarked', permission=OWNER)


So, in this example, let's think about when we serialize Profile into
a dictionary (for later turning into JSON for ajax). user is the only
special case, so skip that mentally for now. Anyone is able to view a
profile's bio. A person can view their own profile's activation status
and what pages they have bookmarked. But only the system can read the
activate_code. Of course the default value for permission would be
ADMIN, so you'd have to explicitly allow fields to be sent to the
browser.

OK, and how would the serialization work? Let's look at a view
function.


from django.shortcuts import get_object_or_404
from django.http import HttpResponse
import simplejson as json

def ajax_profile_info(request, id):
    id = int(id)
    profile = get_object_or_404(Profile, id=id)
    # ok now we want to serialize profile for sending to json.
    # let's say this is the ajax view for getting data about OTHER
people.
    return json_response(profile.serialize(PUBLIC))

def json_response(data):
    return HttpResponse(json.dumps(data), mimetype="text/plain")


So in this view, only fields with the PUBLIC will get rendered into
the dict. Let's say it was a view function for looking at a person's
own account settings. Then we would pass OWNER to the serialize
function and we would get all PUBLIC fields + OWNER fields.

OK that's dandy, but I have one other idea to make serialization
awesome. When you have models that foreignkey all over the place, it's
a pain to create a nice json object that follows the chain to the
exact depth that you want. So let me complicate the model a little
bit.


from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    user = models.ForeignKey(User, permission=PUBLIC)
    bio = models.TextField(permission=PUBLIC)
    activated = models.BooleanField(default=False, permission=OWNER)
    activate_code = models.CharField(max_length=256, permission=ADMIN)
    books_read = models.ManyToManyField('Book',
related_name='profile_pages_bookmarked', permission=PUBLIC)

class Book(models.Model):
    title = models.CharField(max_length=100, permission=PUBLIC)
    protagonist = models.ForeignKey('Character', permission=PUBLIC)
    language_used = models.ForeignKey('Language', permission=PUBLIC)
    cover_art_plan = models.ForeignKey('CoverArtPlan',
permission=PUBLIC)
    internal_admin_thing = models.IntegerField(permission=ADMIN)

class Character(models.Model):
    name = models.CharField(max_length=100, permission=PUBLIC)

class Language(models.Model):
    name = models.CharField(max_length=100, permission=PUBLIC)

class CoverArtPlan(models.Model):
    name = models.CharField(max_length=100, permission=PUBLIC)

OK so let's say I'm making a page where we see all the books a person
has read (and the info about those books). Here's a view function:


def ajax_books_read(request, profile_id):
    id = int(id)
    profile = get_object_or_404(Profile, id=id)
    return json_response(profile.serialize(PUBLIC),
['books_read.protagonist', 'books_read.language_used'])


So this second argument, the serialize_chain, says that we want to
serialize profile into a dict, and the books_read field, instead of
containing a list of ids, should contain a list of serialized Books.
And since we have a dot there, when Profile passes it's serialization
request on to Book, it cuts off the "books_read." and passes the rest
to Book, so that book sees ['protagonist', 'language_used']. so when
Book serializes, its 'protagonist' field is the serialization of the
Character instead of just an id. Same for 'language_used'. However,
since cover_art_plan was not included, it is simply the id of the
CoverArtPlan instead of following the link. Also of note, since we
serialized with PUBLIC, internal_admin_thing is completely left out of
Book's serialized data.

A note about access levels: let's say Profile was serialized with
OWNER access, when it serializes its books_read, it doesn't pass
OWNER, it de-escalates the access level to PUBLIC. However if you
serialize Profile with ADMIN access, it does pass admin when it
serializes its links. Think about it; it makes sense.


Anyways, I would like to know if

1) Does a solution like this already exist? and if not
2) Is this cool enough to go into django core? or contrib or whatever.


I got some feedback from mattmcc in #django:
<mattmcc> superjoe: At first glance, I'd be more inclined to look at a
role-based access control mechanism that doesn't obligate hardcoding
permission levels on to model fields..

However I don'

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

Reply via email to