I have a model and form with a TimeField and I want to make a change for the hour once the timefield is extracted from the form that was submitted and stored. I want to update the hour in the time. can anyone help me with this...
here is the view
start_time = cd['start_time']
hour = start_time.hour
new_hour = hour - int(alert)
update_time = start_time
update_time.hour = new_hour
update_time.save()
So the start_time is a timefield that submitted.
I want to grab the hour from that start time to change it. how can i do that...
this is the error essage I am getting:
attribute 'hour' of 'datetime.time' objects is not writable
I want to grab the hour from the original time and updated/change it
datetime instances are immutable, but there is a method to get a new instance with one (or serveral) of the fields replaced with a different value. It's documented here: https://docs.python.org/3/library/datetime.html#datetime.datetime.replace
So your example would become something like this:
start_time = cd['start_time']
update_time = start_time.replace(hour=start_time.hour - int(alert))
I'm not sure why you are calling save on update time. I'm assuming that's a mistake in your example.
Related
There is a field start_time of type datetime in processes table. The initial value is set to Time.zone.now. After that the user is not allowed to change the date, only hour and minute of that start_time field is allowed to change.
So, an edit form is provided to the user that shows only hour:minute like "22:43" but when the form is submitted the field value is changed to current date and time. In the controller I've used the standard rails statement to update the values:
#process = Process.find(params[:id])
#process.update(process_params)
In the params I get the start_time as "20:40"
Also tried the change method but it not saving the changes instead it rollbacks.
hour_minute = params[:process][:start_time].split(":")
#process.start_time.change({hour: hour_minute[0], min: hour_minute[1]})
I want to update only hour and minute of the field date should remain the same.
change method return changed time or date but didn't update active record it self.
you can do this for update.
hour_minute = params[:process][:start_time].split(":")
#process.update(start_time: #process.start_time.change(hour: hour_minute[0], min: hour_minute[1]))
Hope, this will help you.
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
I encountered a model like this:
class Task(models.Model):
timespan = models.IntegerField(null=True, blank=True)
class Todo(models.Model):
limitdate = models.DateTimeField(null=True, blank=True)
task = models.ForeignKey(Task)
I need to extract all Todos with a limitdate that is lower or equal to today's date + a timespan defined in the related Task model.
Something like (dummy example):
today = datetime.datetime.now()
Todo.objects.filter(limitdate__lte=today + F('task__timespan'))
Now, I can do that with a loop but I'm looking for a way to do it with F(), and I can't find one.
I'm starting to wonder if I can do that with F(). Maybe I should use extra ?
Please note that I don't have the luxury of changing the model code.
The main issue is that DB does not support date + integer and its hard to write ORM query to date + integer::interval, for PostgreSQL for example, where integer is the value of the task_timespan column, in days count.
However, as
limitdate <= today + task__timespan equals to
limitdate - today <= task__timespan
We could transform the query to
Todo.objects.filter(task__timespan__gte=F('limitdate') - today).distinct()
thus the SQL becomes something like integer >= date - date, that should work in PostgreSQL because date - date outputs interval which could be compared w/ integer days count.
In other DBs such as SqLite, it's complicated because dates need to be cast w/ julianday() at first...and I think you need to play w/ extra() or even raw() to get the correct SQL.
Also, as Chris Pratt suggests, if you could use timestamp in all relative fields, the query task might become easier because of less limited add and subtract operations.
P.S. I don't have env to verify it now, you could try it first.
The problem is that there's no TIMESPAN type on a database. So, F cannot return something that you can actually work with in this context. I'm not sure what type of field you actually used in your database, but the only way I can think of to do this is to the store the timespan as an integer consisting of seconds, add that to "today" as a timestamp, and then convert it back into a datetime which you can use to compare with limitdate. However, I'm unsure if Django will accept such complex logic with F.
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.
This is driving me crazy. I've used all the lookup_types and none seem to work.
I need to select an object that was created two weeks ago from today.
Here's what I've got:
twoweeksago = datetime.datetime.now() - datetime.timedelta(days=14)
pastblast = Model.objects.filter(user=user, created=twoweeksago, done=False)
The model has a created field that does this: created = models.DateTimeField(auto_now_add=True, editable=False)
But my query isn't returning everything. Before you ask, yes, there are records in the db with the right date.
Can someone make a suggestion as to what I'm doing wrong?
Thanks
DateTimeField is very different from DateField, if you do
twoweeksago = datetime.datetime.now() - datetime.timedelta(days=14)
That is going to return today's date, hour, minute, second minus 14 days, and the result is going to include also hours minutes seconds etc. So the query:
pastblast = Model.objects.filter(user=user, created=twoweeksago, done=False)
Is going to find for a instance was created just in that exact time, If you only want to care about the day, and not hours, minutes and seconds you can do something like
pastblast = Model.objects.filter(user=user, created__year=twoweeksago.year, created__month=twoweeksago.month, created__day=twoweeksago.day, done=False)
Check the django docs:
https://docs.djangoproject.com/en/1.4/ref/models/querysets/#year