0

Data :

{
  "Fruit": "Pomegranate",
  "District": "Nasik",
  "Taluka": "Nasik",
  "Revenue circle": "Nasik",
  "Sum Insured": 28000,
  "Area": 1200,
  "Farmer": 183
}

{
  "Fruit": "Pomegranate",
  "District": "Jalna",
  "Taluka": "Jalna",
  "Revenue circle": "Jalna",
  "Sum Insured": 28000,
  "Area": 120,
  "Farmer": 13
}

{
  "Fruit": "Guava",
  "District": "Pune",
  "Taluka": "Haveli",
  "Revenue circle": "Uralikanchan",
  "Sum Insured": 50000,
  "Area": 10,
  "Farmer": 100
}

{
  "Fruit": "Guava",
  "District": "Nasik",
  "Taluka": "Girnare",
  "Revenue circle": "Girnare",
  "Sum Insured": 50000,
  "Area": 75,
  "Farmer": 90
}

{
  "Fruit": "Banana",
  "District": "Nanded",
  "Taluka": "Nandurbar",
  "Revenue circle": "NandedBK",
  "Sum Insured": 5000,
  "Area": 2260,
  "Farmer": 342
}

{
  "Fruit": "Banana",
  "District": "Jalgaon",
  "Taluka": "Bhadgaon",
  "Revenue circle": "Bhadgaon",
  "Sum Insured": 5000,
  "Area": 220,
  "Farmer": 265
}

I want to write all types of combination queries, if someone wants information only for Fruit which is Guava then the output will be exact data for Guava only.

also if someone wants information only for Fruit which is Banana & Guava then the output will be exact data for Banana and Guava.

If fruit is equal to Banana

output will be data for Banana

If fruit is equal to Guava

output will be data for Guava

If fruit is equal to Banana and Guava

output will be data for Banana and Guava

Also, if someone wants information only for District which is Nasik then the output will be exact data for Nasik district only. Query for "District"

If District is equal to Nasik

output will be data for Nasik District

If District is equal to Nanded

output will be data for Nanded District

likewise, there is query for "Revenue_circle, Farmer etc.

I know how to write this queries in mongoshell using find

db.Wbcis.find({"Fruit":"Banana"})

db.Wbcis.find({"District":"Nasik"}) etc...

but I want to writing the queries in the python script so I am confuse in models.py and views.py file.

I tired and type query using Q objects in models.py

models.py

from django.contrib.auth.models import User

from django.db import models

from django.db.models import Q

class Wbcis(models.Model):  
  Fruit = models.CharField(max_length=50)  
  District = models.CharField(max_length=50)   
  Taluka = models.CharField(max_length=50)    
  Revenue_circle = models.CharField(max_length=50)   
  Sum_Insured = models.FloatField()   
  Area = models.FloatField()
  Farmer = models.IntegerField()


def __str__(self):

    return self.Fruit

def save(self, *args, **kwargs):

    super().save(*args, **kwargs)

class Meta:

  verbose_name_plural = 'wbcis'

from models import Wbcis
Guava =Wbcis.objects.filter(Q(Fruit='Guava'))
print Guava
Banana= Wbcis.objects.filter(Q(Fruit='Banana'))
print Banana  
Pomegranate= Wbcis.objects.filter(Q(Fruit='Pomegranate'))   
print Pomegranate
Guava_Banana=Wbcis.objects.filter(Q(Fruit='Guava')&Q(Fruit='Banana'))   
print Guava_Banana

But, I know this is not correct way for query. I need to write this in for loop or while loop. can you please help me for how to writing this query using for loop ?

Zagorodniy Olexiy
  • 2,132
  • 3
  • 22
  • 47
Kiran Prajapati
  • 191
  • 2
  • 18

1 Answers1

1

I'm not sure what you want, but your queries seem correct.

I think what you mean with your for loop, is that you can iterate over a query (technically, a QuerySet) to get the results.

For example:

Guava = Wbcis.objects.filter(Q(Fruit='Guava'))
for guava_entry in Guava:
    # Do something with the returned element here:
    print guava_entry

If you want to filter by multiple things, you can just have multiple conditions in your filter. For example, to get Bananas in Nanded

Guava = Wbcis.objects.filter(Fruit="Banana", District="Nanded")

You don't need to use a for loop for that. By default, filter combines your conditions using and. That means that in the example above, Fruit must be "Banana", and District must be "Nanded".

Looking at the examples you have in your question, you have this query:

Guava_Banana=Wbcis.objects.filter(Q(Fruit='Guava')&Q(Fruit='Banana'))   

This query will never return any results. It is asking for an object that has both a Fruit of "Guava" and a Fruit of "Banana". What you want instead is this:

Guava_Banana=Wbcis.objects.filter(Q(Fruit='Guava') | Q(Fruit='Banana'))

This new query returns objects where fruit is either "Guava" or "Banana".

I understand this can be confusing, because you want to return Guavas and Bananas, but think of it as a boolean expression.

You can wrap this in a function like this:

def get_wbcis(fruit=None, district=None, talkua=None, min_farmer=None, max_farmer=None, limit=100):
    query = Wbcis.objects.all()
    if fuit is not None:
        query = query.filter(Fruit=fruit)

    if district is not None:
        query = query.filter(District=district)

    if taluka is not None:
        query = query.filter(Taluka=taluka)

    if min_farmer is not None:
        query = query.filter(Farmer__gte=min_farmer)

    if max_farmer is not None:
        query = query.filter(Farmer__lt=max_farmer)

    return query[:limit]

The limit parameter ensures that at most that many results are returned.

min_farmer in this example uses the __gte query operator, meaning that results with a Farmer greather than or equal to min_farmer will be returned.

max_farmer uses the __lt operator, so results with a farmer lower than, but not equal to max_farmer will be returned.

Similarly, you could use __gt or __lte if you want different different inequality filters.

Your views.py could do something like this:

import json
from django.forms.models import model_to_dict
from django.http import JsonResponse
from models import get_wbcis

def wbcis_view(request):
    fruit = request.GET.get("fruit")
    district = request.GET.get("district")
    taluka = request.GET.get("taluka")
    min_farmer = request.GET.get("min_farmer")
    max_farmer = request.GET.get("max_farmer")

    wbcis = get_wbcis(fruit, district, taluka, min_farmer, max_ffarmer)

    #convert them to JSON:
    dicts = []
    for wbci in wbcis:
        dicts.append(model_to_dict(wbci))

    return JsonResponse(dicts)
bigblind
  • 12,539
  • 14
  • 68
  • 123
  • yes I want to iterate over a query. suppose we want data output for some fruit in some taluka then how to write query? – Kiran Prajapati Dec 21 '16 at 10:14
  • so, we need to write all queries in this form? for District=Pune for District=Nasik....so on ? or using for loop we can do this? – Kiran Prajapati Dec 21 '16 at 10:17
  • 1
    Do you mean you'd want to group fruits by district? So for example, get all the fruits in Pune, and then all the fruits in Nasik and so on? – bigblind Dec 21 '16 at 10:18
  • yes . exactly... suppose I want data for banana fruit in nanded district, then output gives me answer. or if someone want data for Guava fruit in nasik district then output gives me answer – Kiran Prajapati Dec 21 '16 at 10:22
  • yes this is helpful, so, I need to write all types of query in models.py file for call it this query i need to write in views.py file? if someone want information for "pune"district -select taluka --"uralikanchan" and select fruit --banana , then output will gives exact this http:127.0.0.1:8000/api/?District=Pune&?Taluka=uralikanchan&Fruit=Banana – Kiran Prajapati Dec 21 '16 at 10:42
  • yes ... fruit is either "Guava" or "Banana". Guava_Banana=Wbcis.objects.filter(Q(Fruit='Guava') | Q(Fruit='Banana')) this is I want.. – Kiran Prajapati Dec 21 '16 at 10:45
  • 1
    You can wrap your query in a function, which you can call from your view. See my updated answer for info. – bigblind Dec 21 '16 at 10:48
  • Okay, so this function I need to write in views.py file? if someone use "Taluka" instead of "district" to find fruits. then what we have to do? for example : in taluka : "Haveli" how many fruits are made? so we need to use Taluka instead of District in wrap function? – Kiran Prajapati Dec 21 '16 at 10:53
  • 1
    You can put this function anywhere you want, but I'd put it in `models.py`, and then your view can call it. To add more search criteria, you can just add parameters to your function. – bigblind Dec 21 '16 at 10:55
  • Oh okay sir , so we can add more parameters likewise def get_wbcis(fruit=None, district=None, taluka=None, farmer=None): if someone want information for district =Pune , revenue_circle=Uralikanchan for farmer there are more than 100 then match this 3 parameters criteria and show exact answer, there I am confuse. how to write this types of query, – Kiran Prajapati Dec 21 '16 at 11:02
  • 1
    I just updated my answer with more function parameters, so yes, you can extend this to farmer, revenue_circle, etc. I'm not sure what you mean with the "if there are more than 100 then match this 3 parameters criteria. In the current version, it'll just match every parameter you pass in, and give you the exact result. If you want to limit the number of results that are returned, you can put [:100] after your query. (updating my answer...) – bigblind Dec 21 '16 at 11:10
  • for example: we want to show data output where farmer is less than 100 in our data . So, we can get data output 2 out of 6. like Q(farmer_lt=100) show only 2 output which is strictly less than 100 farmers. but there some specific criteria that is in District=> Nasik, how many data gives farmers are less than 100 to made fruit ==> Guava. – Kiran Prajapati Dec 21 '16 at 11:18
  • 1
    You can use Farmer__lt=100 to filter farmers below 100. I updated my answer. With this, you could say 127.0.0.1/api/?district=Nasik&fruit=Guava&max_farmer=100 to get the example you gave. – bigblind Dec 21 '16 at 11:28
  • thank you very much. it's really helpful for me..!! :) – Kiran Prajapati Dec 21 '16 at 11:30
  • If we want to filter by multiple things, For example, Areas to get Bananas in Nanded Guava = Wbcis.objects.filter(Area_lt=100,Fruit="Banana", District="Nanded") is this correct? – Kiran Prajapati Dec 21 '16 at 11:34