0

I am new to Django and I have to create webpages which takes the following inputs: location, technology, and services. The first web page should select a location type, and based on that it goes to the next page which selects the technology according to the location. the third web page selects services based on both the technology and location selected previously(it will be the intersection of both).For that i have to create schemas where each location can have multiple technologies and services, where both are independent of each other, and each technology multiple services.

eg: loc1_tech->tech1,tech2
    loc2_service->service1,service2,service3
    tech1_service->service1,service2
    tech_service2->service3,service4,service5

If we select loc1, then the next web page shows tech1 and tech2, and if i select tech2, then the third web page shows service3 only, which is the intersection of services of loc1 and tech2. I am planning to create 3 schemas- loc_tech, loc_services, tech_services in models.py. Is this the efficient way to go about it and create schemas? Also, how will i find the intersection of web services for the third webpage?

ICoder
  • 149
  • 1
  • 3
  • 9

1 Answers1

0

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.

Shivam Sharma
  • 901
  • 1
  • 6
  • 12
  • Thanks for your answer! It seems to be correct, I am not sure about the code in views.py which you have mentioned, it shows an error for me for the line: technologies = location.technologies.all(), that it is an invalid statement. Can you please re-confirm it – ICoder Jul 16 '17 at 22:52
  • also with get(), we will be able to retrieve one value only, if i am not wrong. In this case i need to get multiple values. – ICoder Jul 16 '17 at 23:12
  • @Ishi I've update the answer. Please check if it helps. Thanks. – Shivam Sharma Jul 17 '17 at 03:51