Question

I have some middleware which takes a tuple (of usernames... it only allows usernames in the tuple to pass through certain areas of the site).

I have a UserProfile model which contains information about each user, and I want to filter it so that it returns a tuple of usernames for use with this middleware -- in otherwords, set a variable BETA_USERS = (dynamically-generated-tuple).

Have you got any suggestions for accomplishing this?

Edit:

So, the tuple really isn't an important detail -- here's an example:

Generally, I would just hard-code this into settings:

BETA_USERS = ('username1', 'username2', 'username3', 'username4')

However, I have a UserProfile model which contains a Beta column, which can be set to 1. The first 50 people to sign up for the beta will be set to 1, everyone else 0. So, I can easily filter this by calling a filter method on a model object:

users = UserProfile.objects.filter(beta='1')

and I can make that a nice tuple with this strange little loop:

for user in users:
    list.append((user.user.username).upper())
return tuple(list)

I guess my real question is, what is the best way for me to call this in my settings file?

or, stated another way, what's the best way to assign dynamically created variables in the settings file?

Was it helpful?

Solution

You can also use the @user_passes_test decorator to restrict views to particular subsets of users. Or create your own decorator:

from django.utils.functional import wraps

def beta(view):
    @wraps(view)
    def inner(request, *args, **kwargs):
        if request.user.user_profile.beta:
            return view(request, *args, **kwargs)
        # Up to you how you return failure...
    return inner

Now you can use it as:

@beta
def my_view(request):
    # do something new here.

The alternative is:

@user_passes_test(lambda u: u.profile.beta)
def my_view(request):
    # do something clever

The advantage of the @beta form is that it is a bit easier to re-use.

OTHER TIPS

The first thing which comes to mind is to build a list then call tuple(), or make a tuple on the fly using a generator function yielding each user name. Either way you will need to build an interface for your data. I've skimmed this site and it seems your data is best accessed by an interface accessing an object's global object. Simply iterate through your django.model objects and extract your user name, yielding each time to a generator used to make a tuple.

Tim has a good answer, if you want to continue to do how you are now doing it.

But, django provides a good way to let only some people into the areas of the site, via custom permissions.

You should implement them and decorate the views that require permission with the @permission_required

I'm not sure if I understand your problem correctly. Is it something like this?

>>> allowed_users = ("John", "Eric", "Graham", "Terry")
>>> current_users = ("Connie", "John", "Ian", "Terry")
>>> tuple(user for user in current_users if user in allowed_users)
('John', 'Terry')

A better solution (thanks to sukhbir for reminding me!):

>>> set(allowed_users) & set(current_users)
{'John', 'Terry'}

or, if the result has to be a tuple:

>>> tuple(set(allowed_users) & set(current_users))
('John', 'Terry')

The only drawback when using a set is that order will not necessarily be preserved.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top