Django Timezone Aware Input Form Setting DateTime In Wrong Timezone
У меня есть модель Order, в которой есть поле DateTimeField. В формах я использую виджет DateTimeInput, чтобы позволить пользователю выбрать время даты. Я также следовал документации Django для того, чтобы позволить пользователю выбрать свой местный часовой пояс, для представления DateTimes. Они хранятся в UTC, но отображаются для пользователя в его местном часовом поясе. Проблема в том, что когда заказ создается с DateTime, он интерпретируется как находящийся в UTC, а не в местном часовом поясе. Так, например, если пользователь находится в часовом поясе Нью-Йорка и создает новый заказ в 12:00 утра 6 апреля по нью-йоркскому времени, он будет сохранен как 12:00 утра 6 апреля по UTC. Таким образом, когда ордер будет отображен обратно пользователю, его DateTime будет 8:00 вечера 5 апреля по нью-йоркскому времени. Это неправильно. Я хочу, чтобы заказ хранился в 4:00 утра 6 апреля по UTC, чтобы он отображался пользователю как созданный в 12:00 по нью-йоркскому времени. Я прочесываю Интернет уже несколько дней, но не могу найти решение этой проблемы. Я разместил часть своего кода ниже:
Модель заказа
class Order(models.Model):
item = models.ManyToManyField(MenuItem)
time = models.DateTimeField(null=True)
Settings.py
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
middleware.py
import zoneinfo
from django.utils import timezone
class TimezoneMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
tzname = request.session.get('django_timezone')
if tzname:
timezone.activate(zoneinfo.ZoneInfo(tzname))
else:
timezone.deactivate()
return self.get_response(request)
set_timezone.html
{% extends 'inventory/base.html' %}
{% load tz %}
{% get_current_timezone as TIME_ZONE %}
{% block content %}
<div class="sign-up">
<form action="{% url 'set_timezone' %}" method="POST">
{% csrf_token %}
<label for="timezone">Time Zone:</label>
<select id="tz-select" name="timezone">
{% for city, tz in timezones.items %}
<option value="{{ tz }}"{% if tz == TIME_ZONE %} selected{% endif %}>{{ city }}</option>
{% endfor %}
</select>
<input class='input-btn' type="submit" value="Set">
</form>
</div>
{% endblock %}
forms.py
# date-time widget for use with OrderCreateForm
class DateTimeInput(forms.DateTimeInput):
input_type = 'datetime-local'
class OrderCreateForm(forms.ModelForm):
class Meta:
model = Order
fields = ('time', 'item')
widgets = {
'time': DateTimeInput(attrs={),
'item': forms.SelectMultiple()
}
views.py
class OrderCreateView(LoginRequiredMixin, CreateView):
model = Order
context_object_name = 'orders'
success_url = reverse_lazy('orderlist')
template_name = 'inventory/orderCreateForm.html'
form_class = OrderCreateForm
def post(self, request, *args, **kwargs):
# Create new Order object, fill fields with input from POST request
newOrder = Order.objects.create()
# retrieve list from manytomany field in POST request, add to new Order object
items = request.POST.getlist('item')
for x in items:
newOrder.item.add(x)
newOrder.time = request.POST['time']
newOrder.save()
return redirect('orderlist')
На самом деле, после пересмотра моего кода при его размещении, я считаю, что виновником может быть:
newOrder.time = request.POST['time']
newOrder.save()
Тип newOrder.time - str, что заставляет меня думать, что он теряет данные о часовом поясе. Однако я могу ошибаться, поэтому буду благодарен за любую другую информацию о том, что может идти не так. Спасибо!
Edit: ошибка подтверждает мои подозрения выше
C:...\django\db\models\fields_init_.py:1416: RuntimeWarning: DateTimeField Order.time получило наивное время (2022-04-07 04:31:00) при активной поддержке часовых поясов. warnings.warn("DateTimeField %s получило наивное время (%s)"
.