think about these:
here is a function,
def calculate(model):
model.tempfield = 1
and this function will save a temp field in this model
and you can use model.tempfield in everywhere
but if it's a queryset,after an order_by these temp filed will lost
how to order_by these temp field in queryset?
i have 2 model:
Class A(models.Model):
name = models.CharField(maxlength=100)
Class Log_Of_A(models.Model):
clicks = models.IntegerField()
a = models.ForeignKey(A)
date = models.DateField(db_index=True)
and calculate the Log of A by date
def createlog(request):
start = request.GET.get("start")
end = request.GET.get("end")
all_A = A.objects.all()
for a in all_A:
logs=Log_Of_A.objects.filter(a=a,date__gt=start,date__lt=end)
statistics = logs.aggregate(Sum("clicks"))
a.clicks = statistics["clicks__sum"]
all_A.order_by("clicks")
return all_A
how to order_by temporary field
Try this:
import operator
def createlog(request):
start = request.GET.get("start")
end = request.GET.get("end")
all_A = A.objects.all()
for a in all_A:
logs=Log_Of_A.objects.filter(a=a,date__gt=start,date__lt=end)
statistics = logs.aggregate(Sum("clicks"))
a.clicks = statistics["clicks__sum"]
sorted = sorted(all_A, key=operator.attrgetter('clicks'), reverse=True)
return sorted
Related
I have the following view I have implemented to filter transactions depending on a certain query provided. Is there a way I could filter dynamically depending on what query is provided, for example one would want to only query year and month only or even filter using one query. The rest of the query values will end up having a None value an should not be included in the filter.
class ReportTransactionsFilterAPIView(APIView):
def get(self, request, format=None):
year = self.request.GET.get('year')
month = self.request.GET.get('month')
subcounty = self.request.GET.get('subcounty')
ward = self.request.GET.get('ward')
fromDate = self.request.GET.get('fromDate')
toDate = self.request.GET.get('toDate')
qs = LiquorReceiptTrack.objects.all()
qs = LiquorReceiptTrack.objects.filter(
Q(date_recieved__range=[fromDate,toDate])|
Q(date_recieved__year=year)|
Q(date_recieved__month=month)|
Q(sub_county__iexact=subcounty)|
Q(ward__iexact=ward)
)
You can use django-filter for your solution. Also for more information you can visit https://www.django-rest-framework.org/api-guide/filtering/
Just use if, why Q do you use here?:
year = self.request.GET.get('year')
month = self.request.GET.get('month')
subcounty = self.request.GET.get('subcounty')
ward = self.request.GET.get('ward')
fromDate = self.request.GET.get('fromDate')
toDate = self.request.GET.get('toDate')
qs = LiquorReceiptTrack.objects.all()
if year:
qs = qs.filter(date_recieved__year=year)
if month:
qs = qs.filter(date_recieved__month=month)
...
Went over the django-filter documentation and refactored the list view:
class TransactionFilter(django_filters.FilterSet):
date_range = DateFromToRangeFilter()
month = django_filters.NumberFilter(field_name='date_recieved', lookup_expr='month')
year = django_filters.NumberFilter(field_name='date_recieved', lookup_expr='year')
date = django_filters.DateFilter(field_name='date_recieved', lookup_expr='exact')
sub_county = django_filters.CharFilter(lookup_expr='icontains')
ward = django_filters.CharFilter(lookup_expr='icontains')
class Meta:
model = LiquorReceiptTrack
fields = ['date','month','year','date_range','sub_county','ward']
class ReportTransactionsFilterAPIView(generics.ListAPIView):
queryset = LiquorReceiptTrack.objects.all()
serializer_class = ReceiptDetailSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = TransactionFilter
i want to change the filtering field dynamically.
i have a model named Product and fields are title and code
class Product(models.Model):
title = models.CharField(max_length=50)
code = models.CharField(max_length=50)
my filtering field will be dynamic in views like this
def filter(request):
search_choices = {
'1': 'title__icontains',
'2': 'code__icontains',
}
col_num = request.GET.get("col_num")
value = request.GET.get("value")
search_field = search_choices.get("col_num")
qs = Product.objects.filter(search_field=value)
........
here the variable search_field is always dynamic ... so how can i achieve this
You can achieve this by passing argument as dictionary:
value = request.GET.get("value")
search_field = search_choices.get("col_num")
qs = Product.objects.filter(**{search_field: value})
I want to filter query based on three user inputs. Depart City, Arrive City and Date. Depart City and Arrive city are on the same table called Route while the TravelDate is a foreign key in Route.
My model
class TravelDate(models.Model):
start_date = models.DateField(null = True)
interval = models.IntegerField(null = True)
class Route(models.Model):
depart_city = models.CharField(max_length=50, null=True, blank=False)
arrive_city = models.CharField(max_length=50, null=True, blank=False)
driver = models.ForeignKey(Driver)
schedule = models.ForeignKey(Schedule)
traveldate = models.ForeignKey(TravelDate)
My View
def newpage(request):
if 'origin' in request.GET and request.GET['origin']:
q = request.GET['origin']
c = request.GET['dest']
d = request.GET['travelDate']
results = Route.objects.filter(depart_city=q, arrive_city=c)
return render(request,'busapp/newpage.html', {'results': results})
else:
return render(request, 'busapp/newpage.html',{})
In Views how can i make one query that will filter depart_city, arrive_city, and TravelDate of those routes based on user inputed. If a bus is available on that date from city A to city B will be calculated by doing doing something like this if (d - TravelDate.start_date)% TravelDate.interval =0 then display the results to the user.
I cannot get this right. I'm new to Django and trying to learn.
Keep interval as IntegerField
views.py
from datetime import datetime, timedelta
q = request.GET['origin']
c = request.GET['dest']
d = request.GET['travelDate']
# d format is '20171122',convert str to date
start_date = datetime.strptime(d, "%Y%m%d").date()
results = Route.objects.filter(depart_city=q, arrive_city=c)
routes = []
for route in results:
if (start_date > date) and ((start_date - route.traveldate.start_date) % timedelta(days=route.traveldate.interva)) == timedelta(days=0):
routes.append(route)
return render(request,'busapp/newpage.html', {'results': routes})
I have models.py
class employees(models.Model):
emp_id=models.PositiveIntegerField()
emp_name = models.CharField(max_length = 100)
emp_lname = models.CharField(max_length = 100)
emp_loc=models.CharField(max_length=5,choices=LOCATION)
manager_id=models.ForeignKey('self',null=True,blank=True)
class leave(models.Model):
employee = models.ForeignKey(employees, on_delete=models.CASCADE, default='1')
start_date = models.DateField()
end_date = models.DateField()
status=models.CharField(max_length=1,choices=LEAVE_STATUS,default='P')
ltype=models.CharField(max_length=2,choices=LEAVE_TYPE)
message=models.CharField(max_length=500,blank=True)
class notify(models.Model):
sender_id=models.ForeignKey(leave, related_name='%(class)s_sendername')
receiver_id=models.ForeignKey(leave,related_name='%(class)s_receivername')
date_time=models.DateTimeField()
I have views.py
def accept(request):
approved_emp_id=leave.objects.filter(id=accept_id);
approving_emp_id=leave.objects.filter(employee__emp_id=request.user.username);
accept_notify=notify(sender_id=approving_emp_id, receiver_id=approved_emp_id,date_time=datetime.datetime.now(),viewed='N');
accept_notify.save()
When I want to save values to database I am getting error as ValueError: Cannot assign "<QuerySet [<leave: 121-geeta-2017-10-04-2017-10-06-C-V-2017-09-27 07:48:36.288873+00:00>]>": "notify.sender_id" must be a "leave" instance.
Where am I going wrong approving_emp_id and approved_emp_id are both leave instance only.
You are passing a QuerySet when the arguments should be an instance. A QuerySet is a list of instances. Pass only one instance. Use leave.objects.get() instead of leave.objects.filter().
objects.get() returns a single instance where objects.filter() returns a QuerySet.
def accept(request):
approved_emp_id = leave.objects.get(id = accept_id)
approving_emp_id = leave.objects.get(employee__emp_id = request.user.username)
accept_notify = notify(sender_id = approving_emp_id, receiver_id = approved_emp_id, date_time = datetime.datetime.now(), viewed = 'N')
accept_notify.save()
Another way is slicing the QuerySet.
def accept(request):
approved_emp_id = leave.objects.filter(id = accept_id)[0]
approving_emp_id = leave.objects.filter(employee__emp_id = request.user.username)[0]
accept_notify = notify(sender_id = approving_emp_id, receiver_id = approved_emp_id, date_time = datetime.datetime.now(), viewed = 'N')
accept_notify.save()
If have a model like:
class Person(models.Model):
id = models.IntegerField()
first_name = models.CharField(max_length=50)
last_name = models.IntegerField()
birthday = models.DateField()
address = models.CharField(max_length=250)
phone = models.TimeField()
To create Person class objects I get data from a stored procedure, like:
cursor = connection.cursor()
cursor.callproc('sp_get_person_by_id', {id:1234})
results = cursor.fetchall()
[Person(*row) for row in results]
But "sp_get_person_by_id" returns more fields than the Person class attributes. Therefore "shit happens", error happens because there is fields that don't have attributes to map.
It's possible to just map this attributes? How can I do that?
Thx in advance.
Cheers.
If you know the order of the attributes you're getting back from the stored procedure you can pass them to the Model like this:
cursor = connection.cursor()
cursor.callproc('sp_get_person_by_id', {id:1234})
results = cursor.fetchall()
result_list = []
from row in results:
p = self.model(id=row[0], fist_name=row[1], last_name=row[2], birthday=row[3])
result_list.append(p)
return result_list