Using a combination of foreign keys is models.py and related_name property in views.py might help you with your issue.
models.py should look something like :
from django.utils.translation import ugettext_lazy as _
class Location(models.Model):
name = models.CharField(_('Location Name') , max_length = 32)
#other fileds you may want to put.
class Technology(models.Model):
name = models.CharField(_('Technology Name') , max_length = 32)
location = models.ForeignKey(Location , related_name="technologies")
#other fileds you may want to put.
class Service(models.Model):
name = models.CharField(_('Service Name') , max_length = 32)
location = models.ForeignKey(Technology , related_name="services")
#other fileds you may want to put.
Now in views :
def get_technologies(request , location_pk=None):
location = Location.objects.get(pk = location_pk)
technologies = location.technologies.all()
#technologies queryset gives you the all the technologies in the location chosen.
#return a HttpResponse()
def get_services(request , technology_pk=None):
technology = Technology.objects.get(pk = technology_pk)
services = technology.services.all()
#services queryset gives you the all the services in the technology(which comes fromt he location chosen earlier) chosen.
#return a HttpResponse()
Note: technology_pk and location_pk are to be sent by your client side as a parameter. They have to accpeted by your urls.py.
Of course you will have to configure the urls.py to accept the parameters, technology_pk and location_pk. Also, alternatively you can use,
location_pk = request.GET.get('location_pk' , None)
location = Location.objects.get(pk = location_pk)
where 'location_pk' in request.GET.get('location_pk' , None)
is sent by your client side.
EDIT:
For multiple instances of locations or technologies sent to the server, the approach would be somewhat different. As you said we'd have to use filter() instead of get().
For obtaining technologies,
def get_technologies(request):
locations = request.POST.getlist('location[]')
#Above, you have to obtain the list of locations that are selected by the user. Request method can be GET as well.
locations_selected_queryset = Location.objects.filter(pk__in = locations)
#For the above statement to work, the list: "locations" should contain the "pk" values of all the locations selected by the user.
result_technologies = list()
for location in location_selected_queryset:
technologies_for_one_location = location.technologies.all()
result_technologies.append(technologies_for_one_location)
#Change the variable names best suited to you. I tried to name them to give more understanding.
Now, result_technologies will have the list of list of different querysets, made up by querysets that are brought by all the locations selected by the user. If you print it in the console, it'll look something like
[[ < Technology : "str value"> , Technology : "str value"> , Technology : "str value"> , ...], [ , Technology : "str value"> , Technology : "str value"> , ...] , ....]
i.e : List of list of querysets.
Now you'll have a problem of joining the querysets obtain, since list of list of querysets will create confusion.see here how to join querysets
Joining can simply be done as,
from itertools import chain
#In your views.py, inside the function get_technologies()
def get_technologies(request):
#...
#...
for location in location_queryset:
technologies_for_one_location = location.technologies.all()
result_technologies.append(technologies_for_one_location)
final_result = list(chain(*result_technologies))
#final_result will be a single list with all the querysets you want.
Hope this helps. Thanks.