I want to update the date from the backend views in django how can i did that here are my views where i want to do this
explaining what i exactly want to achive i am building a crm where clients suppose to pay monthly or quaterly depends on their plan i have given a button at dashbord which triggers this function and redirect to homepage in this function if the user date month came then this function is suppose to generate the bills which is fetching in the homepage and show outstanding amount what wrong happen with this idea everytime pressing the button it will genertate duplicate bills adding in revenue to stops this i add a variable is eligible which i thought the user will change it manually but then i feel it is more good to update the date
def refresh_dashboard(request):
date = datetime.datetime.now().strftime ("%Y%m%d")
m = datetime.date.today()
print(f"the date is {m}")
customer = Customer.objects.all()
for i in customer:
# print(i.eligible)
period = i.next_payment.strftime("%Y%m%d")
if period <= date and i.eligible == True:
x = Bill.objects.create(name = i.name,status ="unpaid",price = i.recuring_amount,generate_date = date)
x.save()
obj = i
# obj.next_payment.strftime("%Y%(m+1)%d")
obj.eligible = False
obj.save()
# print(f"the date is {date} and the obtain from the customer is {period}")
# print(f"this customer {i.name} bill need to be generated")
# print(f"the date is {datetime.datetime.now()}")
return redirect('/')
You can increment datetime on the basis of given days using timedelta
from datetime import datetime
from datetime import timedelta #new
today = datetime.now()
print(f"Today's the date & Time is {today}")
month_later = today+ timedelta(days=MONTHLY_CYCLE)
three_months_later = today+ timedelta(days=QUA_CYCLE)
six_months_later = today+ timedelta(days=SIX_MONTH_CYCLE)
print(f"three_months_later's the date & Time is {month_later}")
print(f"three_months_later's the date & Time is {three_months_later}")
print(f"six_months_later's the date & Time is {six_months_later}")
customer = Customer.objects.get(pk=id) # Targeted Customer
selected_cycle = int(customer.billing_cycle) #return the value of billing_cycle selected from Customer
tentative_date = today+ timedelta(days=selected_cycle)
print(f"tentative_date Billing date & Time is {month_later}") # Required DAte.
This is how you can update the datetime. rest you can implement as required.
Related
I have a problem with lookup that looks for a value in related set.
class Room(models.Model):
name = models.Charfield(max_lentgh=64)
class Availability(models.Model):
date = models.DateField()
closed = models.BooleanField(default=False)
room = models.ForeignKey(Room)
Considering that there is one availability for every date in a year. How can use ORM query to find whether room withing given daterange (i.e. 7 days) has:
availability exist for every day within given daterange
none of the availabilities has closed=True
I was unable to find any orm examples that check whether all objects within daterange exist
You can enumerate over the dates, and ensure that it has for that date an Availability with closed=False:
from datetime import date, timedelta
rooms = Room.objects.all()
start_date = date(2022, 7, 21) # first day
for dd in range(7): # number of days
dt = start_date + timedelta(days=dd)
rooms = rooms.filter(availability__date=dt, availability__closed=False)
The rooms will after the for loop have a QuerySet with all Rooms that have for all dates in that range Availability objects with closed=False.
I'm working on a Quiz app and one question gets uploaded every week in a month (4 ques/month). Now I want to make sure that a logged in user can only attempt the question twice per week and not more than that. How can I do this using throttling or any other way?
Here's my Quiz model:
Days = (
("Mon", "Monday"),
("Tue", "Tuesday"),
("Wed", "Wednesday"),
("Thu", "Thursday"),
("Fri", "Friday"),
("Sat", "Saturday"),
("Sun", "Sunday")
)
class QuizDetail(models.Model):
name = models.CharField(max_lenght=255, blank=False, null=False)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
publisehd_week_day = models.CharField(max_length=255, choices=Days)
The published_week_day can change every month, so basically one month it can be Tuesday and next month it can be Thursday.
Note: If in a month published_week_day is Tuesday and a user attempts last week's quiz on Monday and exhausts his two attempts then on Tuesday he should be able to attempt as it will be a fresh quiz.
Store it in another field
I am assuming end_date only stores the last time the quiz ended.
Create a field, say count. Now increase count by 1 everytime a test is attempted. If it reaches above 2, dont allow the quiz to be taken.
What about resetting it?
You could calculate it every single time you make the request. However this is clearly extremely ineffiecient. Therefore, I would do something like so:
Create another process.(Have a look at Simple approach to launching background task in Django)
That process constantly searches through the database at fixed intervals.
If it finds that a week has passed since the last time the user took the test, it resets the count to 0. To do this simple subtract current datetime(datetime.now()) with end_time and compare it to 2 weeks.
You have to create one model which basically would have a relationship with your QuizDetail model
class UserQuizAttempt(models.Model)
quiz = models.ForeignKey(QuizDetail, on_delete=models.CASCADE)
user = models.ForeginKey(User, on_delete=models.CASCADE)
attempt_made_on = models.DateTimeField(auto_now_add=True)
so in your views.py file, where the user will make an API call to attempt the quiz you have to check whether the user has made any attempt for that particular quiz in that particular week. If it is exceeding 2 then just return a response saying that he's exceeding the limit of the attempt for the week.
a basic example could look like this
from datetime import date
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
class QuizAPI(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
def check_user_attempts(self, request, quiz_instance):
current_week = date.today().isocalendar()[1]
attempts = UserQuizAttempt.objects.filter(attempt_made_on__week=current_week=current_week, quiz=quiz_instance, user=request.user)
if attempts.count() > 2:
return False
return True
def post(self, request):
quiz_id = request.data.get('quiz_id')
quiz_instance = QuizDetail.objects.get(id=quiz_id)
if self.check_user_attempts(request, quiz_instance):
UserQuizAttempt.objects.create(quiz=quiz_instance, user=request.user)
# your logic goes here
...
else:
return Response("Your attempts exceeding for the week! Please try next week", status=status.HTTP_406_NOT_ACCEPTABLE)
So with this, you will have the history of the user's attempt made on the quiz which can be used for reporting or something.
I have a model class:
class Products(models.Model):
product = models.Charfield( field specs here . )
expiration_date = modelsDateTimeField ( . field specs here . )
Now I want the users to be able to see all the products which will expire in 1 week or/and 1 month or/and 3 months from today.
I have already tried:
from django_filters import rest_framework as filters
expiration_date_after = filters.DateFilter(field_name='expiration_date', lookup_expr='gte')
expiration_date_before = filters.DateFilter(field_name='expiration_date', lookup_expr='lte')
with this, I have to pass two parameters in the url:
/products/?expiration_date_after=2019-06-06&expiration_date_before=2019-06-12
But I want to pass in the url only 1 or 2 or 3 which will display data for 1 week, 2 weeks and 3 weeks .
So if i pass products/1 . it should filters expiration date for next 1 week.
and if i pass products/2 . it should filter expiration date for next 1 month.
I am new to django.... So please let me know what is best approach to this problem.
You should write query like this:
products = Products.objects.filter(expiration_date__range=[start_date, end_date])
if You want on weekley basis than you should do like this:
days = 7*n
start_date = today()
end_date = start_date + datetime.timedelta(days=days)
where n=number of weeks
Note: Do not forget to change date string to datetime object
I implemented this in this manner:
In custom_filters folder:
from Django_filters import rest_framework as filters
from date time import date time, date, timedelta
import datetime
class DaysFromTodayFilter(filters.Filter):
def filter(self,qs,value):
if value not in (None,''):
days_key = int(value):
today = datetime.date.today()
if days_key ==1:
x_days_from_today = today + date time.timedelta(days=7)
elif days_key ==2:
x_days_from_today = today + date time.timedelta(days=14)
return qs.filter(**{'%s__%s'%(self.field_name, 'range'):(today, x_days_from_today)})
return qs
In views.py file:
from Django_filters import rest_framework as filters
from views import DaysFromTodayFilter
from models import Products
import Django_filters
class ProductsFilter(Django_filters.FilterSet):
expiration_date_within = DaysFromTodayFilter(field_name='expiration_date')
It's working fine....
in the url:
localhost:8000/products/1
is filter all products which will expire in 1 week and /2 for two weeks
In a Django app, I keep daily scores of users in such a model:
class Score(models.Model):
user = models.ForeignKey(User)
score = models.PositiveIntegerField(default=0)
date = models.DateField(auto_now_add=True)
I want to find out the days when a user's score has changed drastically compared to a consequent day. That is, if for example, the user scores 10 times higher than the previous day.
How can I include such a condition in a query filter using Django ORM? Is it possible with a single query using conditional expressions as described here: https://docs.djangoproject.com/en/1.9/ref/models/conditional-expressions/
Thanks.
If you change your Score class slightly to include the previous day's score (which is admittedly pretty wasteful), you can pack the query into one line using F expressions.
Your new class:
class Score(models.Model):
user = models.ForeignKey(User)
score = models.PositiveIntegerField(default=0)
lastscore = models.PositiveIntegerField(default=0)
date = models.DateField(auto_now_add=True)
Then the filter becomes:
from django.db.models import F
daily_chg = 10
big_changes = Score.objects.filter(score__gt=daily_chg*F('lastscore'))
Instead of using timedeltas to search for and set the previous day's score field, I'd look into establishing an ordering via a Meta class and calling latest() when saving the current day's score.
Using timedelta we can test for the last week's days for a given user as such:
from my_app.models import Score
import datetime
def some_view(request):
days_with_score_boost = []
today = datetime.date.today()
for each_day in xrange(0,7):
day_to_test, day_before_to_test = today - datetime.timedelta(days=each_day), today - datetime.timedelta(days=each_day + 1)
day_before_score = Score.objects.get(user=request.user,date=today - datetime.timedelta(days=each_day)).score # will need to catch the exception raised if .get return None and process appropriately
if Score.objects.filter(user=request.user,score__gte=days_before_score * 10,date=day_before_to_test).count() > 0:
days_with_score_boost.append(day_to_test)
days_with_score_boost will be a list of datetime.date objects where the score increased by 10 or more from the day before.
In reponse to your comment, I'd make a measure that checks at save time whether the score boost has occured. However, I would get rid of auto_now_add in favor of writing in the save method.
from django.utils import timezone
from django.core.exceptions import ObjectDoesNotExist
class Score(models.Model):
user = models.ForeignKey(User)
score = models.PositiveIntegerField(default=0)
date = models.DateField(null=True,blank=True)
increased_ten_over_previous_day = models.BooleanField(null=True,blank=True)
def save(self, *args, **kwargs):
self.date = timezone.now().today()
try:
yesterday_score = Score.objects.get(date=self.date-timezone.timedelta(days=1)).score
self.increased_ten_over_previous_day = (yesterday_score * 10) <= self.score
except ObjectDoesNotExist: # called if Score.object.get returns no object; requires you only have one score per user per date
self.increased_ten_over_previous_day = False
super(self, Score).save(*args, **kwargs)
Then you could filter objects for a date_range where increased_ten_over_previous_day is True.
I have 2 models called Car and Review . A user can write many reviews for a car.
I am able to filter all the reviews for a certain car .
The issue i'm facing is , I only want to filter all the reviews that belong to a particular car in less than 30 days and excluding the user who own the car.
This question support my question Getting all items less than a month old but I am unable
to filter all the reviews that belong to a particular car in less than 30 days and excluding the user who own the car.
class Car(models.Model):
user = models.ForeignKey(User)
name = models.CharField(max_length=11)
class Review(models.Model):
created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User)
review = models.TextField()
car = models.ForeignKey(Car)
Filter all the review for a particular car
Car = Car.objects.get(pk=1)
Review = Review.objects.filter(car=Car)
Filter all the review for a particular car but it retrieves all the reviews for everycar in 30 days which I don't want . I want to retrieve only the reviews in less than 30 days for a particular car and excluding the user who own the car
Car = Car.objects.get(pk=1)
from datetime import datetime, timedelta
last_month = datetime.today() - timedelta(days=30)
Review = Review.objects.filter(car__in=car,review__gte=month)
My question is How can I filter all the reviews for a particular car in less than 30 days and not including the reviews of the user who own the car .
thank you for helping me
First of all you need to filter on created field rather than on review field to lookup older entries:
from django.db import Q
from datetime import datetime, timedelta
Car = Car.objects.get(pk=1)
threshold = datetime.now() - timedelta(days=30)
# filtering step by step to give better understanding
reviews = Review.objects.filter(car__id=car.id) # filter by car first
reviews = reviews.filter(created__gte=threshold) # filter by datetime
reviews = reviews.filter(~Q(user__id=car.user.id)) # exclude user reviews who owns the car
# filtering in single step
reviews = Review.objects.filter(
~Q(user__id=car.user.id), car__id=car.id, created__gte=threshold)
How about following the relationship 'backwards' (https://docs.djangoproject.com/en/dev/topics/db/queries/#backwards-related-objects) :
from datetime import datetime, timedelta
threshold = datetime.now() - timedelta(days=30)
car = Car.objects.get(pk=1)
reviews = car.review_set.exclude(user=car.user).filter(created__gt=threshold)