0

I'm new to Django and I'm stuck at querying through multiple sets.

I have three models;

class Project(models.Model):
    name = models.CharField(max_length = 100)

class AppointmentGroup(models.Model):
    name = models.CharField(max_length = 100) # not used in design.. delete when not used at the end of the project
    project = models.ForeignKey(Project)
    location = models.ForeignKey(Location)

class Appointment(models.Model):
    appointment_group = models.ForeignKey(AppointmentGroup)
    start_date = models.DateTimeField()
    end_date = models.DateTimeField()

Now I want a returned object set with only the projects that have appointments within a particular year. And that the appointment set objects in the project object contains only the ones in that year!

Is this easy to do with a django query or must i loop through the projects one by one and check all the appointments on the date?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sven van Zoelen
  • 6,989
  • 5
  • 37
  • 48

2 Answers2

1

I'm guessing that the appointment model is some how related to your projects and you just left that off.

You probably want to use range and lookups that span relationships:

import datetime
start = datetime.date(2010, 1, 1)
end = datetime.date(2010, 12, 31)
projects_in_2010 = Projects.objects.filter(appointmentgroup__appointment__start_date__range(start, end))
dting
  • 38,604
  • 10
  • 95
  • 114
  • Ok now i have all the projects that are in that range. But how can i loop through all the appointments of that project object? Then i need to filter the appointmentgroups right? – Sven van Zoelen Apr 08 '11 at 09:54
  • Lets say you want the appointments for the first project of your returned queryset. `project = projects_in_2010[0]` and then `appointments = Appointment.objects.filter(appointment_group__project=project)` – dting Apr 08 '11 at 09:54
  • Ok, but then i get all the appointments returned from that project (also the not 2010 dated). But i get the point, just add the range filter again on that query. Thx man! – Sven van Zoelen Apr 08 '11 at 09:58
0

Try this

AppointmentGroup.objects.filter(appoinment_set__start_date__year=2011, appoinment_set__end_date__year=2011)
rubayeet
  • 9,269
  • 8
  • 46
  • 55
  • re-read the docs here: http://docs.djangoproject.com/en/1.0/topics/db/queries/#following-relationships-backward The _set is used for when you have an object and want to follow a relationship backwards. That won't work for filtering, you just use the lowercased model name. Also you would return AppointmentGroup objects, The question is asking for Project objects queryset. – dting Apr 08 '11 at 08:46
  • @krieger pardon my poor understanding of Django ORM but there seems to be a One-to-Many relationship from AppointmentGroup to Appointment. Isn't that where '_set' comes to play? – rubayeet Apr 08 '11 at 08:59
  • Look at the example that is given in the docs. If you had a AppointmentGroup object, you could use the _set, but you are trying to filter which wouldn't work. For example `ag = AppointmentGroup.objects.get(pk=1)` then you could use `ag.appointment_set.all()` to get all the appointments that are related to that `ag`. Hope that makes sense. To do filtering that span relationships, look at the docs link posted in my answer. – dting Apr 08 '11 at 09:11
  • "You cannot access a reverse ForeignKey Manager from the class; it must be accessed from an instance:" http://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward – dting Apr 08 '11 at 09:16