我的问题是我在 Django 中设置了自定义用户时区设置,并且它仅在第一次页面重新加载后正确设置了TIME_ZONE值。 目前,如果用户登录,他会看到默认的TIME_ZONE设置("美国/New_York"),然后在第一次刷新时看到他自己的时区设置正确(即 - "美国/温哥华")。
这是我的中间件
from django.utils import timezone
class TimezoneMiddleware(object):
def process_request(self, request):
tz = request.session.get('django_timezone')
if tz:
timezone.activate(tz)
这是我的登录视图,它使用 pytz 评估从数据库中的用户获取的字符串时区,并将其放入会话中。 初始登录后,TIME_ZONE不会反映时区。 如果我的模板中有 {{TIME_ZONE}},它会显示为默认设置"美国/New_York"。 刷新页面后,它会显示为"美国/温哥华",即用户的设置。
def login_view(request):
if request.method == 'POST':
user = authenticate(username=request.POST['username'], password=request.POST['password'])
if user is not None:
if user.is_active:
login(request, user)
request.session['user'] = user
userdetails = user.get_profile()
request.session['django_timezone'] = pytz.timezone(userdetails.timezone)
# Prioritize favorite company in index list of companies
return companyHome(request, userdetails.get_favorite_company_id())
这是我的时区提交模板中的表单,它按预期工作并在使用时设置时区。
<form action="{% url 'onBaristaApp:set_timezone' %}" method="POST">
{% csrf_token %}
<label for="timezone">Time zone:</label>
<select name="timezone">
{% for tz in timezones %}
<option value="{{ tz }}"{% if tz == TIME_ZONE %} selected="selected"{% endif %}>{{ tz }}</option>
{% endfor %}
</select>
<input type="submit" value="Set" />
</form>
下面是与之关联的视图。
def set_timezone(request):
user = ViewManager.login_handler(request)
if request.method == 'POST':
new_timezone = pytz.timezone(request.POST['timezone'])
request.session['django_timezone'] = new_timezone
userdetails = user.get_profile()
userdetails.timezone = new_timezone
userdetails.save()
return redirect('/Profile/')
else:
return render(request, 'login.html')
这是自定义用户配置文件中的相关模型字段
class UserProfile(models.Model):
...
timezone = models.CharField(max_length=50, default='America/New_York')
...
这是出现问题的模板
{% extends "base.html" %}
{% load url from future %}
{% load tz %}
{% get_current_timezone as TIME_ZONE %}
{% block body_tag %} home {% endblock %}
{% block contents %}
...
{% for check_in_object in location.get_checkins %}
{% localtime on %}
...
{{ check_in_object }}{{ check_in_object.get_tzobject }}
...
{% endlocaltime %}
...
{% endblock %}
这是方法get_tzobject的代码,它显示了时间,以及模型和字段
class checkIn(models.Model):
...
inTime = models.DateTimeField(null=True)
outTime = models.DateTimeField(null=True)
checkedin = models.BooleanField(default=True)
...
def get_tzobject(self):
if self.checkedin:
timezone_corrected_time = localtime(self.inTime)
else:
timezone_corrected_time = localtime(self.outTime)
activate(timezone_corrected_time.tzinfo)
return timezone_corrected_time
我能够通过在我的login_view代码中添加timezone.activate(pytz.timezone(userdetails.timezone))来解决这个问题。
def login_view(request):
if request.method == 'POST':
user = authenticate(username=request.POST['username'], password=request.POST['password'])
if user is not None:
if user.is_active:
login(request, user)
request.session['user'] = user
userdetails = user.get_profile()
timezone.activate(pytz.timezone(userdetails.timezone))
request.session['django_timezone'] = pytz.timezone(userdetails.timezone)
# Prioritize favorite company in index list of companies
return companyHome(request, userdetails.get_favorite_company_id())