I am building a BlogApp and I am implementing a feature of expiring post so the post will hide in 2 days, So I am showing user the remaining time in post.
Remaining time is showing perfectly BUT It is also showing milliseconds (which i I am trying to hide)
The Output is like :-
2 days, 23:43:33.271449
views.py
from django.utils import timezone
from datetime import timedelta
def blogpost_detail(request,blogpost_id):
blog = get_objects_or_404(BlogPost,pk=blogpost_id)
remaining_time = blog.blog_date_added - timezone.now() + timedelta(days=2)
context = {'remaining_time':remaining_time,'blog':blog}
return render(request, 'blogpost_detail.html', context}
What i am trying to show as output :-
I am trying to show like :-
2 days 23 Hours Remaining
What have i tried :-
I tried Python/Django timestamp including milliseconds Post's Answer by dividing 1000 but when i divide timezone by 1000 like timezone.now()/1000 then it is keep showing
unsupported operand type(s) for /: 'datetime.datetime' and 'int'
Then i tried hiding milliseconds from template by using time:"h:i a" like {{ blog.blog_date_added|time:"h:i a" }}
But it is showing nothing as output.
When i try to add naturaltime like {{ blog.blog_date_added|naturaltime }} then it is showing the same output.
When i try to add timesince like {{ blog.blog_date_added|timesince }} then it is showing :-
'datetime.timedelta' object has no attribute 'year'
Any help would be much Appreciated. Thank You in Advance
I would advise that you add a property to your Blog when the blog will expire, something as:
from datetime import timedelta
class Blog(models.Model):
# ⋮
#property
def expire_date(self):
return self.blog_date_added + timedelta(days=2)
In the template we can then work with the |naturaltime template filter:
{% load humanize %}
{{ blog.expire_date|naturaltime }}
Related
I have an UpdateView and when I visit the edit page, my date field renders the month as non-localized.
In my Form I'm using format("%B %Y") to have the full month + year representation, like so:
class CampaignForm(ModelForm):
date = DateField(widget=DateInput(attrs={"autocomplete": "off"}, format="%B %Y"))
I'm using the form in a basic UpdateView setup, and I render the template...
<div class="form-row">
<div class="form-group flatpickrdatetimeinput col-md-6 mb-0">
{{ form.date|as_crispy_field }}
</div>
</div>
The date representation works in terms of month + year, but I need to localize the month name to the local language.
I cannot find the error, I tried changing the field attribute (localize=True) and also I have played around with the settings (i18n, l10n, etc) with no success.
In fact, the settings have worked out so far. In the same template I am using the 'date' template filter and it translates the month just fine
<h2>{{campaign.date | date:'F Y' }}</h2>
How to make use of the internal django localization inside a form/form-field?
While writing the question, I had the idea to try to set the initial data and localize it there.
It indeed worked but it's a workaround and I still think it should work directly from the form.
If you have a solution please feel free to add it. Or leave a comment if you have experienced the issue and you think this is a bug.
from django.utils import formats
class CampaignUpdateView(CampaignMixin, UpdateView):
def get_initial(self):
initial = super().get_initial()
initial.update({"date": formats.date_format(self.object.date, format="F Y", use_l10n=True)})
return initial
The subject is the simplest way that I can break down the problem that I am getting.
I'm using Django 2.1
settings.py
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'America/New_York'
USE_I18N = True
USE_L10N = True
USE_TZ = True
views.py
message = timezone.now().time
message2 = timezone.now
The above code is the fastest way to show the problem that I have. When I print 'message' I'm given a time different than what I get from 'message2' although they are both pulling the same value.
My model saves a datetimefield using the auto_now_add feature.
models.py
class Comment(models.Model):
date_time = models.DateTimeField(auto_now_add=True, blank=True)
When I display the field in HTML as
{{ comment.date_time }}
the correct date and time appears. However when I use my own formatting and break up the code as
{{ comment.date_time.date }}: {{ comment.date_time.time }}
then I cannot get the time to display in the correct timezone. I've tried the following alterations all to no avail.
{% load tz %}
{% localtime on %}
{{ comment.date_time.time }}
{% endlocaltime %}
{{ comment.date_time.time|localtime }}
{{ comment.date_time.time|timezone:"America/New_York" }}
Does anyone know of a way to address this?
Try this,
pass timezone.now() to timezone.localtime
from django.utils import timezone
timezone.localtime(timezone.now())
More info here.
The problem is that you're using trying to use time objects instead of datetime objects. The localtime and timezone template tags and filters are expecting datetime objects.
If you want a custom format in the template, use the date filter. If for whatever reason that can't give you the format you want, you will need to do the conversion yourself in the view rather than relying on the template, e.g.:
from django.utils.timezone import localtime
def view():
local = localtime(comment.date_time)
date_string = str(local.date()) # or whatever custom format you want
time_string = str(local.time()) # or whatever custom format you want
from django.utils import timezone
timezone.localtime(timezone.now())
Also, in the settings.py you must change:
TIME_ZONE = 'America/New_York'
A list of the time zone database names can be found on: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
I'm trying to create a generic date class based view for the blog I'm creating, but it does not seem to work. This is what I've got (regex inspired by this gist):
"""Creativeflow URL Configuration the blog app."""
from django.conf.urls import url
from .views import BlogListView, BlogDetailView
urlpatterns = [
url(r'posts/(?P<year>\d{4})/(?P<months>\d{2}|\w{3})/(?P<day>\d{2})/(?P<slug>\w+)',
BlogDetailView.as_view(), name="blog-detail"),
url(r'posts(?:/(?P<year>\d{4}))(?:/(?P<months>\d{2}|\w{3}))?(?:/(?P<day>\d{2}))?',
BlogListView.as_view(paginate_by=25), name="blog-list"),
]
And my views:
class BlogListView(ListView):
"""CBV for list of blog posts."""
model = Post
context_object_name = "blog_objects"
def get_query_set(self):
"""Get the posts in the specified date range.
Year defaults to todays year
Month defaults to last month of the year
Day defaults to last day of the month
"""
now = datetime.now()
year = self.kwargs.get('year', now.year)
month = self.kwargs.get('month', 12)
day = self.kwargs.get('day', calendar.monthrange(year, month)[1])
date = datetime.date(year=year,
month=month,
day=day)
print(date)
print('hello')
return Post.objects.filter(published__lt=date)
Going to http://blog.creativeflow.org.uk/posts/2016/07/09 doesn't provide any data up to the template, post_list.html:
{% extends "base.html" %}
{% block content %}
<main>
{% for blog in blog_objects %}
<div>
<h3>{{ blog.title }}</h3>
</div>
{% endfor %}
</main>
{% endblock content %}
(I can provide the base as well if people want)
My intention is that accessing posts/2016 gets all of 2016s posts (because it defaults to the end of 2016, i.e. 2016/12/31), posts/2016/02 gets all of the posts from February 2016 (defaults to the end of Feb 2016, i.e. 2016/02/29) etc. But running resolve('/posts/2016/07/09') produces an error because I'm on a subdomain, and using django-subdomain's from subdomains.utils import reverse works...
>>> reverse('blog-list', subdomain="blog", kwargs={"year":"2016", "months":"02", "day":"13"})
'http://blog.creativeflow.org.uk/posts/2016/02/13'
but my attempt in the browser don't return anything. I'm also not getting anything printed in the terminal when I refresh the page, despite my two print statements.
I feel like there is something drastic that I'm missing that's obvious, but I'm struggling to connect the dots.
How can I make this route work?
This works, my two main issues were
Not having blogs in the DB
As Alasdair said:
You are using the keyword months in your url pattern but month when you try to reverse.
I believe that's all it took to resolve this.
I need a help with time-limit. I want to show user how many time he has got to rent a car.
This is my views:
class CarRentView(RedirectView):
permanent = False
query_string = True
model = Car
def date_of_return(request):
car = Car.objects.all()
car.rent = True
date_of_rent = datetime.now()
date_of_rent = car.save()
car_return_date = date_of_rent+timedelta(days=30)
return render(request, 'cars','car_return_date')
and when I want to do this in my template:
{{ car_return_date }}
there is nothing and I don't know, what's wrong. Is there any possibility to show return date and after this make a count?
You need to call the render function differently:
return render(request, 'myapp/index.html', {'cars': car, 'car_return_date': car_return_date})
See the docs for more information.
Besides, I don't think you are setting the car.rent correctly, since you are setting it on all cars.
Variables that you return to your template need to be returned as part of a context dictionary. So you would have:
return render(request, 'my_template.html', {'car': car, 'car_return_date': car_return_date})
The car_return_date variable will then be available in your template using:
{{ car_return_date }}
You will also probably want to use the date filter when outputting the datetime object. For example, you could use:
{{ car_return_date|date:"j N Y" }}
I would suggest changing date_of_rent to last_date_of_rent by adding 30 days to it. And then, saving last_date_of_rent to the models. So you can use, last_date_of_rent directly in the templates. Further the use of in-built template filter timeuntil will return the desired. -
{{ car.last_date_of_rent|timeuntil }}
Documentation:
https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#timeuntil
I have two dates and want to show a message like "n days left before your trial end." where n is a number of days between two given dates. Is that better to do this inside views or is there a quick way to do it inside template itself?
Use timesince template tag.
This code for HTML in Django. You can easily find the remaining days.
{{ to_date|timeuntil:from_date }}
Otherwise, you can use custom TemplateTags.
Possible duplicate here
I'd actually use the same method lazerscience uses, something like this:
from datetime import datetime, timedelta
from django import template
from django.utils.timesince import timesince
register = template.Library()
#register.filter
def time_until(value):
now = datetime.now()
try:
difference = value - now
except:
return value
if difference <= timedelta(minutes=1):
return 'just now'
return '%(time)s ago' % {'time': timesince(value).split(', ')[0]}
In the HTML template, you can do the following:
{{ comments.created|timeuntil:project.created }}
And you get output something like this:
1 hour, 5 minutes