Issue
Let's say I have a User model and a Dataset model. I want to get all datasets that (have a certain type AND (belong to a certain user OR don't belong to anyone)). What is the best approach to achieve this?
Code sample:
class User(AbstractUser):
username = models.CharField(max_length=150,unique=True,)
first_name = models.CharField(blank=True, max_length=150)
last_name = models.CharField(blank=True, max_length=150)
class Dataset(models.Model):
name = models.CharField(null=False, unique=True, max_length=50)
type = (models.PositiveIntegerField())
UserID = models.ForeignKey(
User,
null=True,
blank=True,
on_delete=models.CASCADE,
related_name="ds_owner",
)
I am trying to figure out how to select something like this:
def view_name(request):
usr = User.objects.get(id=request.user.id)
allowed_datasets = Dataset.objects.filter(type=1 AND (UserID=usr OR UserID__isnull=True))
Solution
You can use Q
objects [Django-doc] to present filtering options as object, and then use &
and |
for conjunctions and disjunctions.
You thus can filter with:
from django.db.models import Q
def view_name(request):
usr = User.objects.get(id=request.user.id)
allowed_datasets = Dataset.objects.filter(
Q(type=1) & (Q(UserID=usr) | Q(UserID=None))
)
or shorter:
from django.db.models import Q
def view_name(request):
usr = User.objects.get(id=request.user.id)
allowed_datasets = Dataset.objects.filter(
Q(UserID=usr) | Q(UserID=None), type=1
)
Note: It is often better to use
get_object_or_404(…)
[Django-doc], then to use.get(…)
[Django-doc] directly. In case the object does not exists, for example because the user altered the URL themselves, theget_object_or_404(…)
will result in returning a HTTP 404 Not Found response, whereas using.get(…)
will result in a HTTP 500 Server Error.
Answered By - willeM_ Van Onsem
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.