DateTime filter in django rest - django

I am creating an api which returns weather data of particular city for n number of days given.(api definition: weatherdata/city_name/ndays/).I have problem sorting out data for ndays.
I sorted out the city name using simple icontains. similarly I want to sort out for ndays. previous ndays data needs to be shown. example: suppose today is 2019-08-29, on providing ndays to be 6, weather data of particular city has to be provided from 2019-08-24 to 2019-08-26.
views.py
class weatherDetail(APIView):
def get_object(self, city_name, ndays):
try:
x = weatherdata.objects.filter(city_name__icontains=city_name)
now = datetime.datetime.now()
fromdate = now - timedelta(days=ndays)
y =
return x
except Snippet.DoesNotExist:
raise Http404
def get(self,*args,**kwargs):
city_name = kwargs['city_name']
snippet = self.get_object(city_name,ndays)
serializer = weatherdataserializer(snippet,many =True)
return Response(serializer.data)
models.py
class weatherdata(models.Model):
city_name = models.CharField(max_length = 80)
city_id = models.IntegerField(default=0)
latitude = models.FloatField(null=True , blank=True)
longitude = models.FloatField(null=True , blank=True)
dt_txt = models.DateTimeField()
temp = models.FloatField(null = False)
temp_min = models.FloatField(null = False)
temp_max = models.FloatField(null = False)
pressure = models.FloatField(null = False)
sea_level = models.FloatField(null = False)
grnd_level = models.FloatField(null = False)
humidity = models.FloatField(null = False)
main = models.CharField(max_length=200)
description = models.CharField(max_length=30)
clouds = models.IntegerField(null=False)
wind_speed = models.FloatField(null = False)
wind_degree = models.FloatField(null = False)
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('weatherdata/', views.weatherList.as_view()),
path('weatherdata/<str:city_name>/<int:ndays>/', views.weatherDetail.as_view()),
]
I want 'y' to be filtering objects based on dates. previous ndays data has to be returned. get_object should return the objects which falls under both x and y what needs to be modified in my code.

You have to change your query like below
class weatherDetail(APIView):
def get_queryset(self, city_name, ndays):
x = weatherdata.objects.filter(city_name__icontains=city_name)
today_date = timezone.now().date()
fromdate = today_date - timedelta(days=ndays)
x = x.filter(dt_txt__gte=fromdate).order_by('dt_txt')
return x
def get(self,*args,**kwargs):
city_name = kwargs['city_name']
snippet = self.get_queryset(city_name, ndays)
serializer = weatherdataserializer(snippet, many=True)
return Response(serializer.data)

Related

django creating new record when update existing record

My models of Employee registration is as follow.
class EmployeeRegistration(models.Model):
#Departmental Details
EmpId = models.IntegerField(verbose_name='EmpId')
EmpImage = models.ImageField(default='default.png',upload_to='profile_pic/%Y/%m/%d')
EmpSafetyCard= models.ImageField(default='default.png',upload_to='profile_pic/%Y/%m/%d')
Site = models.ForeignKey(Site,on_delete=models.CASCADE,max_length=150,verbose_name='Site')
Department = models.ForeignKey(Department,on_delete=models.CASCADE,max_length=150,verbose_name='Department')
Category = models.ForeignKey(Category,on_delete=models.CASCADE,max_length=150,verbose_name='Category')
Designation = models.ForeignKey(Designation,on_delete=models.CASCADE,max_length=150,verbose_name='Designation')
PfApplicable = models.BooleanField(default = True,verbose_name='Pf Applicable')
EsiApplicable = models.BooleanField(default = True,verbose_name='Esic Applicable')
Uan = models.PositiveIntegerField(null = True,verbose_name='Uan')
Esic = models.PositiveIntegerField(null = True,verbose_name='Esic')
AttendenceAward = models.BooleanField(default = True)
AttendenceAllowance = models.BooleanField(default = True)
ProfesionalTax = models.BooleanField(default = False)
Name = models.CharField(max_length=150,verbose_name='Name')
Father = models.CharField(max_length=150,verbose_name='Father')
Dob = models.DateField()
Male = models.BooleanField(default = True)
Female = models.BooleanField(default = False)
MaritalStatus = models.BooleanField(default = True)
Address = models.CharField(max_length=200,verbose_name='Address')
Aadhar = models.PositiveIntegerField(null=True)
pan = models.CharField(max_length=10)
choices = [('Working','WORKING'),('NotWorking','NOT WORKING'),('Leave','Leave')]
Status = models.CharField(choices=choices,blank = False,max_length=10,verbose_name='Status')
Doj = models.DateField(default = date.today)
Doe = models.DateField(blank = True,verbose_name = 'Doe',null = True)
def __str__(self):
return f'{self.Name}({self.EmpId})'
def save(self):
super().save()
empimg = Image.open(self.EmpImage.path)
empsafetycard = Image.open(self.EmpSafetyCard.path)
if empimg.height>300 or empimg.width>300:
output_size = (300,300)
empimg.thumbnail(output_size)
empimg.save(self.EmpImage.path)
if empsafetycard.height>300 or empsafetycard.width>300:
output_size = (300,300)
empsafetycard.thumbnail(output_size)
empsafetycard.save(self.EmpSafetyCard.path)
This is my newEmployeeForm code
class newEmployeeForm(forms.ModelForm):
class Meta:
model = EmployeeRegistration
fields = '__all__'
labels ={
'EmpImage':'Upload Employee Image',
'EmpSafetyCard':'Upload Safety Card',
'Dob':'Date of Birth',
'Doj':'Date of Joining',
'Doe':'Date of Exit'
}
widgets = {
'Dob':DateInput(),
'Doj': DateInput(),
'Doe': DateInput()
}
This is my View for regitering new employee
def registration_view(request,id=0):
form = newEmployeeForm()
record = RecordsId.objects.all()
empid = 0
for data in record:
empid = data.EmpId
emp_id = empid+1
if(empid!=0 or empid==0):
get_emp = RecordsId.objects.get(EmpId=empid)
EmployeeId={"EmpId":emp_id}
print(request.POST)
if(request.method == 'POST'):
if(id==0):
form = newEmployeeForm(request.POST or None,request.FILES,initial=EmployeeId)
print("id= 0")
else:
print(id)
employee = EmployeeRegistration.objects.get(pk=id)
form = newEmployeeForm(instance=employee)
if form.is_valid():
print("valid")
get_emp.EmpId = emp_id
get_emp.save()
form.save()
print("saved")
form = newEmployeeForm(initial=EmployeeId)
messages.success(request,'Successfully Updated')
return redirect('emplist')
else:
print("Form is not valid")
context = {
'form':form,
"contact":"active"
}
return render(request,"employee/NewEmployee.html",context)
I have a view for registering new employee at the same time in the same view i am updating the records of employee. But when i am trying to update the existing record. It is creating new record. i don't know why this is happening. Please help me.

Filter queryset for foreign key

I need to filter the books associated with my serie model
My models.py
class Serie(models.Model):
serie = models.CharField(max_length = 255)
author = models.ForeignKey(Author, on_delete = models.CASCADE, null = True)
slug = AutoSlugField(populate_from = 'serie', always_update = True)
class Book(models.Model):
serie = models.ForeignKey(Serie, on_delete = models.CASCADE, null = True)
serie_slug = AutoSlugField(populate_from = 'serie', always_update = True, null = True)
book_title = models.CharField(max_length=200)
slug = AutoSlugField(populate_from = 'book_title', always_update = True, null = True)
resume = RichTextField()
pub_date = models.DateTimeField(auto_now_add = True, null = True)
My views.py
class index(ListView):
model = Serie
template_name = 'serie_book_list.html'
ordering = ['id']
def get_queryset(self, *args, **kwargs):
context = super().get_queryset(*args, **kwargs)
search = self.request.GET.get('buscar', None)
if search:
context = context.filter(
Q(serie__icontains = search) |
Q(author__name__icontains = search) |
Q(Book.objects.filter(book_title__icontains = search))
)
return context
I tried to use this code Q(Book.objects.filter(book_title__icontains = search)), but without success.
Cannot filter against a non-conditional expression.
your filter Q(Book.objects.filter(book_title__icontains = search)) not match any field in Serie
try this:
context = context.filter(
Q(serie__icontains=search) |
Q(author__name__icontains=search) |
Q(book__book_title__icontains=search))
)

Django: display queryset in its corresponding ID (multiple ID)

My model is like this:
class Hospital(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='author')
hospital_name = models.CharField(max_length=1000)
hospital_ategory = models.CharField(max_length=1000, choices=ETABLISSEMENTS)
imagePopup = models.ImageField(upload_to='default/', default='default/musta.jpg')
wilaya = models.CharField(max_length=200, choices=WILAYA)
active = models.BooleanField(default=True)
location = PointField(srid=4326)
#property
def lat_lng(self):
return list(getattr(self.location, 'coords', []) [::-1])
def __str__(self):
return self.hospital_name
class Hospitalservice(models.Model):
post = models.ForeignKey(Hospital, on_delete=models.CASCADE, related_name='services')
name_service = models.CharField(max_length=10000, null=True, blank=True)
responsable_service = models.CharField(max_length=10000, null=True, blank=True)
service_date = models.DateTimeField(default=timezone.now)
service_update = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
def __str__(self):
return "{} à l'hopital {}".format(self.name_service, self.post.hospital_name)
class Meta:
ordering = ('-service_date', )
class Bedservice(models.Model):
post_bed = models.ForeignKey(Hospitalservice, on_delete=models.CASCADE, related_name='bed')
bed_number_total = models.IntegerField(null=True, blank=True)
bed_number_used = models.IntegerField(null=True, blank=True)
active = models.BooleanField(default=True)
def __str__(self):
return self.post_bed.name_service
`
views.py looks like this:
class HospitalTemplateView(TemplateView):
template_name = 'health/hospital_map.html'
queryset = Hospital.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["form"] = HospitalForm()
...
...
...
return context
def detail_imp_map(request, id):
post = get_object_or_404(Hospital, id=id)
services = post.services.filter(active=True)
post_bed = get_object_or_404(Hospitalservice, pk=id)
bed_service = post_bed.bed.filter(active=True)
columns = ['bed_number_total']
num = reduce(add, (F(column) for column in columns ))
Total_sum= Bedservice.objects.aggregate(total=Sum(num))
if request.method == "POST":
service_form = HospitalServiceForm(request.POST, request.FILES)
if service_form.is_valid():
new_point = service_form.save(commit=False)
new_point.post = post
new_point.save()
return redirect('hospital_map')
else:
service_form = HospitalServiceForm()
context={
'post': post,
'post_bed': post_bed,
'Total_sum': Total_sum,
'services':services,
'service_form':service_form,
}
return render(request, 'health/detail_imp_from_map.html', context)
def detail_hosp_map(request, id):
result = Bedservice.objects.all().annotate(difference=F('bed_number_total') -
F('bed_number_used'))
post_bed = get_object_or_404(Hospitalservice, id=id)
bed_service = post_bed.bed.filter(active=True)
post_medecin = get_object_or_404(Hospitalservice, id=id)
medecin_service = post_medecin.medecin.filter(active=True)
if request.method == "POST":
service_bed_form = BedserviceForm(request.POST, request.FILES)
medecin_service_form = MedecinForm(request.POST, request.FILES)
if service_bed_form.is_valid():
new_point_service_bed = service_bed_form.save(commit=False)
new_point_service_bed.post_bed = post_bed
new_point_service_bed.save()
return redirect('hospital_map')
if medecin_service_form.is_valid():
new_point_service_medecin = medecin_service_form.save(commit=False)
new_point_service_medecin.post_medecin = post_medecin
new_point_service_medecin.save()
return redirect('hospital_map')
else:
service_bed_form = BedserviceForm()
medecin_service_form = MedecinForm()
context={
'result':result,
'bed_service': bed_service,
'medecin_service': medecin_service,
'post_bed': post_bed,
'post_medecin': post_medecin,
'service_bed_form': service_bed_form,
'medecin_service_form': medecin_service_form,
}
return render(request, 'health/detail_service.html', context)
urls.py :
urlpatterns = [
path('admin/', admin.site.urls),
path(r'hospital_map/', HospitalTemplateView.as_view(), name='hospital_map'),
path(r'hospital_map/<int:id>/', detail_imp_map, name='detail'),
path(r'detail_service/<int:id>/', detail_hosp_map, name='detail_service'),
url('^health/', include('health.urls', namespace='health')),
path('add_impact/', addImpactOnMap, name='add_impact'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
By using
columns = ['bed_number_total']
num = reduce (add, (F (column) for column in columns))
Total_sum = Bedservice.objects.aggregate (total = Sum (num))
I get bed_number_total in all departments of all hospitals. So what I want here. How to display the sum of bed_number_total and the sum of bed_number_used for all departments in each hospital (each hospital has its own id). So if anyone can provide any advice on this it would be greatly appreciated.
Assuming you don't want to change your models (you could include the counts in the model).
Without getting into complicated aggregates. In the case you want to count it per hospital you can either loop throught the objects and count it:
hospitals_res = Hospital.objects.all()
result = []
for hospital_find in hospitals_res:
hospitalservices = Hospitalservice.objects.filter(post = hospital_find)
for service in hospitalservices:
bed_services = Bedservice.objects.filter(post_bed = service)
used = 0
total = 0
for bed_serv in bed_services:
used = used + bed_serv.bed_number_used
total = total + bed_serv.bed_number_total
result.append({'hospital_id': hospital_find.id, 'used_beds':used, 'total_beds':total})
Or just use a raw query: (always be careful to escape any parameters passed)
query = """
SELECT
hospital.id as id,
SUM(bedservice.bed_number_total) as total,
SUM(bedservice.bed_number_used) as used
FROM
backend_admin_hospital AS hospital
LEFT JOIN backend_admin_hospitalservice AS hospitalservice ON post_id = hospital.id
LEFT JOIN backend_admin_bedservice AS bedservice ON post_bed_id = hospitalservice.id
GROUP BY hospital.id
"""
result = Hospital.objects.raw(query)

How can I initialize my form Image and Integer fields with model data?

I've managed to initialize a CharField, but how can I do the same with ImageField and IntegerField?
My forms.py:
class GoodGet(forms.ModelForm):
class Meta:
model = Good_Get
Size = forms.ModelChoiceField(queryset = Good.objects.all())
fields = '__all__'
def __init__(self, *args, good_id1=None, **kwargs):
super(forms.ModelForm, self).__init__(*args, **kwargs)
if good_id1 is not None:
obj = Good.objects.filter(id = good_id1)
self.fields['Name'].initial = Good.objects.get(id=good_id1)
self.fields['Photo'].initial = Good.objects.get(id=good_id1)
self.fields['Price'].initial = Good.objects.get(id=good_id1)
for good in obj:
good_sizes = good.Size.all()
self.fields['Size'].queryset = good_sizes
So, I need to write these strings correctly:
self.fields['Photo'].initial = Good.objects.get(id=good_id1)
self.fields['Price'].initial = Good.objects.get(id=good_id1)
How?
Good model:
class Good(models.Model):
Name = models.CharField(max_length = 150)
Type = models.ForeignKey('Type', on_delete=models.CASCADE, null=True)
Available = models.CharField(max_length = 50)
Photo = models.ImageField(upload_to = 'clothes_photos')
Price = models.IntegerField(default = '0')
Discount = models.IntegerField(default = '0')
Size = models.ManyToManyField('Size')
You would be better off initialising this in the view.
good = Good.objects.filter(id = good_id1)
form = GoodGet(instance=good)

filter on related_set in Django query

class Hardware(models.Model):
date = models.PositiveSmallIntegerField()
node = models.ForeignKey('Node', on_delete=models.CASCADE,null = True)
slot = models.PositiveSmallIntegerField(null = True)
server = models.CharField(max_length=20,null = True)
server_state = models.CharField(max_length=20,null = True)
adapter = models.CharField(max_length=20,null = True)
adapter_state = models.CharField(max_length=20,null = True)
class Meta:
unique_together = ('date', 'node','slot')
order_with_respect_to = 'node'
def __str__(self):
return self.node.name +" " + self.server
class Node(models.Model):
name = models.CharField(max_length = 40, primary_key = True)
def __str__(self):
return self.name
def inventory_by_node(request):
day = (arrow.now().day) - 1
nodes = Node.objects.prefetch_related("hardware_set").all()
return render(request, 'automation/inventory_by_node.html',{'nodes':nodes})
I need to filter hardware_set based on date which is equal to currrent day. I tried
nodes = Node.objects.prefetch_related(Prefetch("hardwares", quesryset=Hardware.objects.filter(date=day)).all()
but It didn't works says no Pretch is defined
Try this:
prefetch = Prefetch("hardware_set", queryset=Hardware.objects.filter(date=day))
nodes = Node.objects.prefetch_related(prefetch).all()