Need help to fetch required data from model in django - django

I have below two models,
class user_files(models.Model):
Filename = models.CharField(max_length=50)
Browse = models.FileField(upload_to='img/')
user_uploaded = models.CharField(max_length=50, blank=True)
class share_files(models.Model):
select_file = models.CharField(max_length=300)
from_user = models.CharField(max_length=50)
select_user = models.CharField(max_length=50,default=None)
user_files stores file uploaded by respective user.
and share_files stores shared file name yo user xx by user bb.
I want to show shared files with logged in user in template,
my function for it in view.py is,
def user_files_all(request):
if not request.user.is_authenticated:
return render(request, 'accounts/logout.html')
else:
data = user_files.objects.filter(user_uploaded=request.user)
data1 = share_files.objects.filter(select_user=request.user)
data2 = user_files.objects.filter(Filename=data1.select_file,user_uploaded=data1.from_user)
args = {'data': data,'data1':data1}
return render(request, 'accounts/files.html', args)
but i am getting error for line,
data2 = user_files.objects.filter(Filename=data1.select_file,user_uploaded=data1.from_user)
as attribute select_file is not present for data1. I want data from user_files model for all users and filename selected in data1. And then want to render that in template.
How to achieve that? Need help.
Thanks in advance.

filter(...) is a model manager method, it returns a queryset instead of an object. So you can do:
Use first() or last() method after using filter. Because these methods return a object from the queryset:
data_list = user_files.objects.filter(user_uploaded=request.user)
data1_list = share_files.objects.filter(select_user=request.user)
if data_list.exists():
data= data_list.first()
else:
data = None
if data1_list.exists():
data1 = data1_list.first()
data2 = user_files.objects.filter(Filename=data1.select_file,user_uploaded=data1.from_user) # its a queryset btw
else:
data1 = None
data2 = None # or user_files.objects.none()

.filter() returns a list of objects. So your data1 variable is a list. You cannot just get value of any attribute.
To achieve what you want you could try something like -
data2 = []
for d in data1:
ufs = user_files.objects.filter(Filename=d.select_file,user_uploaded=d.from_user)
for uf in ufs:
include = True
for d2 in data2:
if d2.pk == uf.pk:
include = False
break
if include:
data2.append(uf)
On a side note - your model design does not look good. Consider using ForeignKey. For more refer this.
Hope it helps.
EDIT
If you are using version 1.11 you can use union()
data2 = []
for d in data1:
ufs = user_files.objects.filter(Filename=d.select_file,user_uploaded=d.from_user)
data2 = data2.union(ufs)
I haven't tested the above codes but you get the idea. For more info on union(), look into this.

Related

filtering a queryset, applying more than one filter

My models are:
models.User:
id = pk
username = text
models.Offer
id = pk
description = text
publicationDate = Date
user = Fk(User)
my serializer is:
class UserOfferSerializer(ModelSerializer):
offers = OfferSerializerAll(many=True, read_only=True)
class Meta:
model = User
fields = ('id', 'username', 'offers')
I am trying to apply more than one filter on the queryset:
users = users.filter(offers__publicationDate__range=[startdate, enddate]). prefetch_related(Prefetch('offers', queryset=Offer.objects.filter(
publicationDate__range=[startdate, enddate]))).distinct()
then
users = users.filter(offers__description__icontains=sometext).prefetch_related(Prefetch('offers', queryset=Offer.objects.filter(description__icontains=sometext))).distinct()
First one works fine and the other one throws the following exception:
ValueError: 'offers' lookup was already seen with a different queryset. You may need to adjust the ordering of your lookups.
Update:
My current code is:
if (offerBeginDate != None and offerEndDate != None):
b = offerBeginDate.split('-')
e = offerEndDate.split('-')
startdate = datetime.date(int(b[0]), int(b[1]), int(b[2]))
enddate = datetime.date(int(e[0]), int(e[1]), int(e[2]))
users = users.filter(offers__publicationDate__range=[startdate, enddate])
offers = offers.filter(publicationDate__range=[startdate, enddate])
if (descriptionText != None):
users = users.filter(offers__functionDescription__icontains=descriptionText.strip())
offers = offers.filter(functionDescription__icontains=descriptionText.strip())
users = users.prefetch_related('offers', Prefetch(queryset=offers))
Any help? Thank you all :)))
You can use to_attr argument of Prefetch object to prefetch additional queryset:
users = users.filter(offers__description__icontains=sometext).prefetch_related(
Prefetch('offers', queryset=Offer.objects.filter(
publicationDate__range=[startdate, enddate]), to_attr='date_offers'),
Prefetch('offers', queryset=Offer.objects.filter(description__icontains=sometext), to_attr='description_offers')).distinct()
UPD
If you need dynamically add filters to prefetched queryset you can define it separately like this:
if some_case:
users = users.filter(offers__description__icontains=sometext)
offers=Offer.objects.filter(description__icontains=sometext)
if some_case_2:
users = users.filter(**conditions)
offers = offers.filter(**conditions)
users = users.prefetch_related(Prefetch('offers', queryset=offers))
Now each user in users queryset will have two attributes: user.date_offers and user.description_offers.

Django - Do different queries depending on value of field

I'm stuck on a seemingly simple issue. I want to do a different queryset if sold_data is empty. Is there an effective way to do this? Or do I need to use a for loop and loop over all the listing objects and check each one?
class Listing(models.Model):
list_price = models.IntegerField()
sold_price = models.IntegerField(null=True, blank=True)
... other fields
data = Listing.objects.filter(...) # Note: I had already made other queries
if sold_price == None:
data = data.filter(list_price__gte=1)
else:
data = data.filter(sold_price__gte=1)
You can do it using Q object.
from django.db.models import Q
# your filtered queryset is in 'data' varibale
data.filter(Q(sold_price__isnull=False, sold_price__gte=1) | Q(sold_price__isnull=True, list_price__gte=1))
if you wanna check if an object is None use the is operator
I'm not sure if I did understand your question here is what I get : you wanna filter list_price if the data contains an object with empty value else filter sold_price
You can try this
if data.filter(sold_price__isnull=True).exists():
data = data.filter(list_price__gte=1)
else:
data = data.filter(sold_price__gte=1)

Django : get() returned more than one

I have trouble to get my data from DB.
Basically one teacher can create more no of class_room each class_room contains a title and it has more number of students.
models.py
class class_room(models.model):
user = models.ForeignKey(User,related_name = 'classroom')
title = models.charField(max_length=50)
students = models.ManyToManyField(User,related_name= 'commits',symmetrical=FAlSE)
views.py
def index(request):
user = request.user
Total_class = class_room.objects.get(user = user)
students_list = Total_class.students.all()
class_name = Total_class.title.all()
return render(request,'trial/index.html,{'Total':Total_class ,'no':students_list, 'class_name ':class_name )
When i try to execute this code. i get this error get() returned more than one
Then i removed get() bcoz the user has more number of class_room so i put filter() After that i get 'QuerySet'object has no attribute 'students'
Any help appreciated :(
You have multiple objects for model class_room in the database, with the same user. Either you need to enforce the uniqueness to the user attribute in the models.
Or, you can get the students attribute of the first object in the query like,
Total_class = class_room.objects.filter(user = user).first()
students_list = Total_class.students.all()
or using index,
Total_class = class_room.objects.filter(user = user)[2]
#any element.
EDIT
As per the request of OP, I think the required queryset would be,
student_list = User.objects.filter(class_room__user=request.user)

How to write python-django queries which is ultimately going to call these queries from django

I want to write all types of complex queries,
for example :
If someone wants information "Fruit" is "Guava" in "Pune District" then they will get data for guava in pune district.
htt//api/?fruit=Guava&?district=Pune
If someone wants information "Fruit" is "Guava" in "Girnare Taluka" then they will get data for guava in girnare taluka.
htt://api/?fruit=Guava&?taluka=Girnare
If someone wants information for "Fruit" is "Guava" and "Banana" then they will get all data only for this two fruits, like wise
htt://api/?fruit=Guava&?Banana
But, when I run server then I cant get correct output
If i use http://api/?fruit=Banana then I get all data for fruit which is banana, pomegranate, guava instead of get data for fruit is only banana. So I am confuse what happen here.
can you please check my code, where I made mistake?
*Here is my all files
models.py
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 get_wbcis(fruit=None, district=None, talkua=None, revenue_circle=None, sum_insured=None, area=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 revenue_circle is not None:
query = query.filter(Revenue_circle= revenue_circle)
if sum_insured is not None:
query = query.filter(Sum_Insured=sum_Insured)
if area is not None:
query = query.filter(Area=area)
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]
Views.py
class WbcisViewSet(ModelViewSet):
queryset = Wbcis.objects.all()
serializer_class = WbcisSerializer
def wbcis_view(request):
fruit = request.GET.get("fruit")
district = request.GET.get("district")
taluka = request.GET.get("taluka")
revenue_circle = request.GET.get("revenue_circle")
sum_insured = request.GET.get("sum_insured")
area = request.GET.get("area")
min_farmer = request.GET.get("min_farmer")
max_farmer = request.GET.get("max_farmer")
wbcis = get_wbcis(fruit, district, taluka,revenue_circle,sum_insured,area, min_farmer, max_farmer)
#convert them to JSON:
dicts = []
for wbci in wbcis:
dicts.append(model_to_dict(wbci))
return JsonResponse(dicts)
Serializers.py
from rest_framework.serializers import ModelSerializer
from WBCIS.models import Wbcis
class WbcisSerializer(ModelSerializer):
class Meta:
model = Wbcis
fields=('id','Fruit','District','Sum_Insured','Area','Farmer','Taluka','Revenue_circle',)
whats need changes in this code for call these queries to get exact output?
I don't think that you're actually calling that view, judging by your usage I presume you're calling the viewset itself and then ignoring the query params.
You should follow the drf docs for filtering but essentially, provide the get queryset method to your viewset and include the code you currently have in your view in that
class WbcisViewSet(ModelViewSet):
queryset = Wbcis.objects.all() # Shouldn't need this anymore
serializer_class = WbcisSerializer
def get_queryset(self):
fruit = self.request.query_params.get("fruit")
....
return get_wbscis(...)

jqgrid and django models

I have the following models
class Employee(Person):
job = model.Charfield(max_length=200)
class Address(models.Model):
street = models.CharField(max_length=200)
city = models.CharField(max_length=200)
class EmpAddress(Address):
date_occupied = models.DateField()
date_vacated = models.DateField()
employee = models.ForeignKey()
When I build a json data structure for an EmpAddress object using the django serialzer it does not include the inherited fields only the EmpAddress fields. I know the fields are available in the object in my view as I can print them but they are not built into the json structure.
Does anyone know how to overcome this?
Thanks
Andrew
Inheritance of Django models can get a little tricky. Unless you excplicitly require EmpAddress to be subclass of Address, you might just want to duplicate the fields and let duck typing handle the fact that you aren't following traditional object oriented design. E.g:
class Address(models.Model):
street = models.CharField(max_length=200)
city = models.CharField(max_length=200)
class EmpAddress(Address):
street = models.CharField(max_length=200)
city = models.CharField(max_length=200)
date_occupied = models.DateField()
date_vacated = models.DateField()
employee = models.ForeignKey()
Another shot in the dark you might try is to use jsonpickle (I'm one of the developers), which is "smarter" than the standard json module. The latest code has some great new features, thanks to davvid.
Take a look at: http://www.partisanpost.com/2009/10/django-jquery-jqgrid-example-one/1/ as a solution to your problem. The full serializer allows you to drill down into foreignkey relationships as far as you need to go. I wrote a tutorial example of how to use it to integrate django with JqGrid, which provides an example of just what you are faced with. Hope this helps.
John,
This is view code I am using along with the models is;
def address_grid(request):
employeeId = request.GET.get('employeeId')
if request.GET.get('sidx') == '':
order = 'date_occupied'
else:
order = request.GET.get('sidx')
if request.GET.get('sord') == 'asc':
sort_order = ''
else:
sort_order = '-'
order = sort_order + order
if request.GET.get('page'):
paginated = int(request.GET.get('page'))
else:
paginated = 1
items = int(request.GET.get('rows'))
addresses = EmpAddress.objects.filter(employee__id=employeeId)
for add in addresses:
log.write(add.city+'\n') # Field from address object
total = adresses.all().count()
if total % items > 0:
items_sum = 1
else:
items_sum = 0
pages = total / items + items_sum
if paginated > pages:
paginated = 1
addresses = addresses.order_by(order)[paginated-1)*items:paginated*items]
rows = serializers.serialize("json", addresses, indent=4,)
addresses = '{total:%(pages)s, page:%(page)s, records:%(total)s, rows:%(addresses)s' \
% {'pages':pages, 'page':paginated, 'total':total, 'addresses':rows}
log.write(rows+'\n') #json object no Address fields (city is not included)
#even it is present above
return HttpResonse(addresses, mimetype="application/json")
When I print the addresses objects after the
addresses = EmpAddress.objects.filter(employee__id=employeeId)
line I have all of the objects attributes (both the Address and EmpAddress fields).
But when I print the json object I only have the EmpAddress object attributes excluding the Address attributes.