How do I input current date and time in Django? - django

So I'm a beginner in Django, and recently came up with a question, regarding datetime.
So I'm trying to make a blog-like page. And among the input fields, including title and contents, I want a datetime field as well. However, there is an additional feature that I want to create, which is -- if the user clicks a checkbox right next to the datetime input field, the datetime will automatically change into the CURRENT date and time. So the input field is replaced with the current date and time.
I have no idea on how to create the feature.
I would very much appreciate your help :)

It will be better if you make this behavior to be set automatically to the time of creating the post for the first time, it will not be triggered if you modify the post:
created_at = models.DateTimeField(auto_now_add=True)
If you want to set it to the current time when you modify the post:
modified_at = models.DateTimeField(auto_now=True)

Related

Django: Joining on fields other than IDs (Using a date field in one model to pull data from a second model)

I'm attempting to use Django to build a simple website. I have a set of blog posts that have a date field attached to indicate the day they were published. I have a table that contains a list of dates and temperatures. On each post, I would like to display the temperature on the day it was published.
The two models are as follows:
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
date = models.DateField()
class Temperature(models.Model):
date = models.DateField()
temperature = models.IntegerField()
I would like to be able to reference the temperature field from the second table using the date field from the first. Is this possible?
In SQL, this is a simple query. I would do the following:
Select temperature from Temperature t join Post p on t.date = p.date
I think I really have two questions:
Is it possible to brute force this, even if it's not best practice? I've googled a lot and tried using raw sql and objects.extra, but can't get them to do what I want. I'm also wary of relying on them for the long haul.
Since this seems to be a simple task, it seems likely that I'm overcomplicating it by having my models set up sub-optimally. Is there something I'm missing about how I should design my models? That is, what's the best practice for doing something like this? (I've successfully pulled the temperature into my blog post by using a foreign key in the Temperature model. But if I go that route, I don't see how I could easily make sure that my temperature dates get the correct foreign key assigned to them so that the temperature date maps to the correct post date.)
There will likely be better answers than this one, but I'll throw in my 2ยข anyway.
You could try a property inside the Post model that returns the temperature:
#property
def temperature(self):
try:
return Temperature.objects.values_list('temperature',flat=True).get(date=self.date)
except:
return None
(code not tested)
About your Models:
If you will be displaying the temperature in a Post list (a list of Posts with their temperatures), then maybe it will be simpler to code and a faster query to just add a temperature field to your Post model.
You can keep the Temperature model. Then:
Assuming you have the temperature data already present in you Temperature model at the time of Post instance creation, you can fill that new field in a custom save method.
If you get temperature data after Post creation, you cann fill in that new temperature field through a background job (maybe triggered by crontab or similar).
Sometimes database orthogonality (not repeating info in many tables) is not the best strategy. Just something to think about, depending on how often you will be querying the Post models and how simple you want to keep that query code.
I think this might be a basic approach to solve the problem
post_dates = Post.objects.all().values('date')
result_temprature = Temperature.objects.filter(date__in = post_dates).values('temperature')
Subqueries could be your friend here. Something like the following should work:
from django.db.models import OuterRef, Subquery
temps = Temperature.objects.filter(date=OuterRef('date'))
posts = Post.objects.annotate(temperature=Subquery(temps.values('temperature')[:1]))
for post in posts:
temperature = post.temperature
Then you can just iterate through posts and access the temperature off each post instance

Django store the original value of a field

I am a newbie with Django trying to create a dashboard application reporting on some key milestone dates. I want to be able to track how the key dates are changing. For example:If the kick off date has been changed 5 times I want to be able to report 1. the first date entered, 2. Current date, 3. The date before the last update.
Thank you
Your question is not clear. But for the logic you have asked one thing we can do is to make a model in which the edited dates and user will be fields. Use user as foreign key of your User model. I will just give an example model.
class Dates(models.Model):
event = models.ForeignKey(Event)
date = models.DateField()
This is a very basic method which i am saying. This is a bit complex and you will have to check if the field has changed five times and all.
For a better answer please make the question clear.

Is is possible to query django ORM by last updated object?

I know I can easily grab the latest entered object, but assuming an update is made to an object in the middle of the pack lets say object 50 of 100, is there a way to query the database to grab that latest update? I.e. number 50, since it was the latest to be updated as opposed to entered into the db?
I searched online and couldn't find anybody trying to accomplish this.
Thanks,
If your model have a DateTimeField with auto_now=True, you can use QuerySet.latest method with that field name specified.
For example, assuming that Model has a field DateTimeField updated_at with auto_now set:
last = Model.objects.lastest('updated_at')

Django wipe datefield value from view

Bit of a random question but ill try my best to describe what im trying to do. I am building a app to manage a set of physical assets which get loaned out.
To return an asset the user visits /return/1/ which clears the name of the user, date borrowed, date returned etc
view.py
def returnlaptop(request, laptop_pk):
Laptops.objects.filter(pk=laptop_pk).update(laptop_status='In')
Laptops.objects.filter(pk=laptop_pk).update(user='')
Laptops.objects.filter(pk=laptop_pk).update(borrowed_date='')
Laptops.objects.filter(pk=laptop_pk).update(return_date='')
return HttpResponseRedirect('/')
This works well except for when i try and update the values in the models.datefield
[u"' ' value has an invalid date format. It must be in YYYY-MM-DD format."]
Is there anyway around this? or am I going about this the completely wrong way?
Cheers
Xcom
I'm not 100% sure but I think that hits the database 4 times...
The first issue is that update is meant for use on a queryset. You are filtering on the primary key so you are only getting 1 object back. Which means that you should use get instead like this
laptop = Laptops.objects.get(pk=laptop_pk)
and now you can use that to properly fetch the object from the database, modify it, and save it like so
laptop = Laptops.objects.get(pk=laptop_pk)
laptop.laptop_status = 'In'
laptop.user = ''
...
laptop.save()
which would only hit the database 1 time.
The final issue is that you are attempting to set a date to an empty string. That won't work because it is expecting a date object. One thing you can do is modify your model so that the dates can be blank and so that the database accepts null values.
class Laptops(models.Model):
...
borrowed_date = models.DateField(null=True, blank=True)
return_date = models.DateField(null=True, blank=True)
The other thing you can do is use the minimum date can be accessed with timezone.datetime.min

Add an IntegerField to a Datefield in a Django template

I'm trying to display the expiry date of a bonus from within a Django template. At the moment the opening_date is stored as a datefield and we store the bonus term as an integerfield. Unfortunately just trying to add the bonus term to the opening date fails and the furthest I have got so far is:
{{product_form.instance.opening_date|add:product_form.instance.bonus_term}}
I have tried just adding it to the month but unfortunately I need the whole date returned to display.
For a better idea of what I want is say the opening date was 01/01/2012 and the bonus term was 12, I want to display the expiry date of 01/01/2013. I realise this is probably better off being in the database but due to the way it has been previously set up there is a large amount of existing data that wouldn't have it.
Thanks.
I think that, for your scenario, the most elegant solution is to create a model method in your model that calcule expire date, then call the method in template:
In model:
class product(models.Model):
opening_date = ...
bonus_term = ...
def expire_date( self ):
return self.opening_date + timedelta( days = self.bonus_term )
In template:
{{product_form.instance.expire_date}}
I'm sure that you will call this method in more other lines of your code.