I've got two models. Event and Usercart.
class UserCart(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=None)
class Event(models.Model):
order = models.ForeignKey(UserCart, on_delete=models.CASCADE, null=True, blank=True)
start_time = models.DateTimeField()
I'd like to develop a queryset of UserCart instances where there is a related event that is in the past (based on that event's start time)
pastcarts = UserCart.objects.filter(????)
Thanks for your help!
This should be as easy as:
pastcarts = UserCart.objects.filter(event__start_time__lt=<whatever_dt_you_prefer>)
You can read more in docs - check for reverse foreign key filtering.
Related
I am using Django Rest Framework and I have this query in raw SQL but I want to do it in the Django ORM instead.
I have tried using the different Django tools but so far it has not given me the expected result.
select tt.id, tt.team_id, tt.team_role_id, tt.user_id from task_teammember tt
inner join task_projectteam tp on tp.team_id = tt.team_id
where tp.project_id = 1
models
class TeamMember(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
team = models.ForeignKey(Team, on_delete=models.CASCADE)
team_role = models.ForeignKey(TeamRole,on_delete=models.CASCADE)
state = models.IntegerField(default=1)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(default=None, null=True)
class ProjectTeam(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE, blank=True, null=True)
team = models.ForeignKey(Team, on_delete=models.CASCADE, blank=True, null=True)
state = models.IntegerField(default=1)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(default=None, null=True)
If you have a project object already then this should get you what I believe you want. Your TeamMember model has access to Team, which links to ProjectTeam, and to Project - the double-underscore accessor navigates through the relationships.
TeamMember.objects.filter(team__projectteam__project=project)
I would advise to span a ManyToManyField over the ProjectTeam, this will make queries simpler:
from django.conf import settings
class TeamMember(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
updated_at = models.DateTimeField(auto_now=True)
# …
class Team(models.Model):
projects = models.ManyToManyField(Project, through='ProjectTeam')
# …
class ProjectTeam(models.Model):
# …
updated_at = models.DateTimeField(auto_now=True)
Then you can easily filter with:
TeamMember.objects.filter(team__projects=project_id)
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Note: Django's DateTimeField [Django-doc]
has a auto_now=… parameter [Django-doc]
to work with timestamps. This will automatically assign the current datetime
when updating the object, and mark it as non-editable (editable=False), such
that it does not appear in ModelForms by default.
I think it's goes like:
TeamMember.objects.filter(team__projectteam__project__id=1)
Django orm allow reverse foreginkey lookup
I'm trying to create an API using the REST Framework. I ran into a little problem. I want to be able to get a list of events for a specific user by sending a request to the API. Is there a possibility to check if the User sending the request is in the team the event belongs to when an event list is requested?
class Teams(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(max_length=1000, blank=True)
Users = models.ManyToManyField(User, blank=True)
class Event(models.Model):
created = models.DateTimeField(auto_now_add=True)
eventTime = models.DateTimeField()
title = models.CharField(max_length=100, default='')
description = models.TextField(max_length=1000, blank=True)
group = models.ForeignKey(Teams, on_delete=models.CASCADE)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
those are the realtionships between the models i implemented so far
You can do that by overwriting .get_queryset(). This should do the trick:
class EventList(generics.ListAPIView):
def get_queryset(self):
#
return Event.objects.filter(group__users=self.request.user)
Querying many-to-many fields is (in my opinion) not very intuitive.
Event.objects.filter(group__users=self.request.user) basically means "get all events that have a group/team that contain the current user".
I've got two models that I'd like to perform a reverse search on. I'm wondering how to do this given the fact that one model has to fields with foreign keys to the same model.
class Review(models.Model):
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, default=None)
class Cart(models.Model):
cost = models.DecimalField(max_digits=50, decimal_places=2, null=True, blank=True)
class Job(models.Model):
cart = models.ForeignKey(Cart, related_name="cart_one", on_delete=models.CASCADE, null=True, blank=True)
unscheduled_job = models.ForeignKey(Cart, related_name="cart_two", on_delete=models.CASCADE, null=True, blank=True)
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, null=True, blank=True)
My query is as follows:
reviews = Review.objects.filter(cart__job__employee=employee)
This query is failing due to the fact that the Job model has two foreign keys that point to the cart model. How would I fix this?
Thanks!
If you specify a related_query_name=… parameter [Django-doc] or a **related_name=… parameter [Django-doc], then that is the name to access the model in reverse, so you can query with:
Review.objects.filter(cart__cart_one__employee=employee)
or if you want to query in reverse with the unscheduled_job, then it is:
Review.objects.filter(cart__cart_two__employee=employee)
You can also combine the two, so bo5th cart anfd unscheduled_job by making use of a Q object:
from django.db.models import Q
Review.objects.filter(Q(cart__cart_one__employee=employee) | Q(cart__cart_two__employee))
You might however want to change the related_name=…s, since this should be the name to access the Job object from the perspective of a Cart model.
I've got 3 models. I'd like to write a query in django to find all reviews that are related to Carts that are related to jobs that are complete. Unfortunately, I can't figure out how to do this.
class Review:
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, default=None)
class Job:
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, default=None)
complete = models.BooleanField(default=False)
class Cart:
name = models.CharField(max_length=500, null=True, blank=True)
amount = models.IntegerField()
Any help would be appreciated!
You can .filter(…) [Django-doc] with:
Review.objects.filter(cart__job__complete=True)
One can use double underscores (__) to look "through" relations.
This will thus retrieve all Reviews for which a related Cart exists for which a related Job exists that has complete=True.
In the past, I think there was a model atrtibute named unique_for to define a foreignKey but I can't find it anymore.
Suppose a model named Recommendation. A User can recommend many websites but only one by domain. So, I wanted to set a unique_for('user', 'recommendation.domain') or something like like this.
What's the current way to do it ?
Recommendation Model:
class Recommendation(models.Model):
is_recommended = models.BooleanField(default=True)
what = models.ForeignKey('Website', on_delete=models.CASCADE)
who = models.OneToOneField(User, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
why = models.CharField(max_length=255, null=True, blank=True)
when = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-when"]
User Model is the Django built in.
Thanks
I've found my answser.
The attribute is unique_together and not unique_for