how can i limit my django foreign key selection by a property stored in the django session
i have a small application i am implementing with django and i'm having a slight challenge. I'm trying to limit the queryset for my relationships within my application by a particular property. Now the catch is, the exact value of the property isn't known until the user logs into the application. an example is limiting a set of comments by a user's particular company, and the company is only determined when the user logs in. I don't know how to find my current session outside a django view. Any help is appreciated. Thank开发者_如何学编程s
Here is a sample of a model from my application
class Tax(commons.models.EntityBase):
name = models.CharField(blank=False, max_length=150)
percentage_value = models.DecimalField(max_digits=4, decimal_places=2)
notes = models.TextField(blank=True, null=True)
auto_apply = models.NullBooleanField()
aggregated_tax = models.NullBooleanField()
def __unicode__(self):
return self.name
Every entity inherits from the abstract class EntityBase
, which holds the property company
. I want to filter every query from the query manager such that they only return entities who's company are equal to the company in the session.
It is perfectly ok to pass your session property, user or company or whatnot, to other functions in different parts of your system.
For example:
def view(request):
user = request.user
filtered_stuff = my_filter_function(..., user = user)
The my_filter_function
may filter on the argument or may pass on the argument to other functions.
The best way that I've found to do this is using a custom QuerySet
and Manager for your model. The accepted answer to this question, should get you started with this part. In your QuerySet
, you can set up a method (I prefer to call it for_user
), which filters your objects for you:
class Foo(models.Model):
ts = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, blank=True, null=True)
due_date = models.DateField(auto_now=False)
objects = CustomQuerySetManager()
class QuerySet(QuerySet):
def for_user(self, user):
return self.filter(user=user)
From there, your view is fairly simple:
def view(request):
user = request.user
mylist = Foo.objects.for_user(user).filter(due_date__lte=datetime.date.today())
To add to Jack's answer, your CustomQuerySetManager would be something like:
class CustomQuerySetManager(models.Manager):
def get_query_set(self):
return self.model.QuerySet(self.model)
def __getattr__(self, attr, *args):
return getattr(self.get_query_set(), attr, *args)
I prefer this method over writing manager methods because it allows you to have chainable functions, therefore you could do:
Foo.objects.for_user(user).filter(...)
精彩评论