Итак, я новичок в Django, и я пытаюсь реализовать на практике следующую идею: в моей форме создания объекта я хочу, чтобы пользователи заполняли поле даты, чтобы поместить временную метку на объект. Загвоздка в том, что я хочу сделать доступными для выбора только два дня — сегодня и завтра. Я не хочу использовать поле DateTime и заставлять пользователей вводить даты вручную, так как это выглядит довольно уродливо и не очень удобно в использовании. Я решил попробовать реализовать поле выбора. Он хорошо отображается, но до сих пор я не понял, как сделать так, чтобы мои данные формы проходили как действительные. Я поковырялся с pdb, в результате прочитал о методах очистки/проверки, но я до сих пор не знаю, как заставить это работать. То, что я уже пробовал: добавление функций, которые возвращают сегодня и завтра в виде объектов даты и в виде строк (вот последнее), текст ошибки: выберите правильный выбор, не является одним из доступных вариантов. Я вижу, что он терпит неудачу во время очистки () способ как-то. Или, если это неразумная идея (что, вероятно, так и есть), какая может быть альтернатива?
модели.py:
def get_today():
return datetime.date.strftime( datetime.datetime.now().date(), format="%Y-%m-%d")
def get_tomorrow():
return datetime.date.strftime(((datetime.datetime.now() + datetime.timedelta(days=1)).date()), format="%Y-%m-%d")
class User(AbstractUser):
slug = models.SlugField(max_length=100, unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.username)
super(User, self).save(*args, **kwargs)
class Task(models.Model):
TODAY = get_today
TOMORROW = get_tomorrow
DATE_SELECTION = (
(TODAY, "Today"),
(TOMORROW, "Tomorrow"),
)
task_title = models.CharField(verbose_name="Название задачи: ", max_length=150)
task_description = models.TextField(verbose_name="Описание: ", max_length=1000)
task_user = models.ForeignKey('User', on_delete=models.CASCADE)
task_date = models.DateField(choices=DATE_SELECTION)
def __str__(self):
return self.task_title
представление на основе классов из views.py, которое я использую для обработки формы:
class CreateTask(CreateView):
model = Task
form_class = TaskForm
success_url = '/{user}'
def get(self, request, *args, **kwargs):
form = TaskForm()
return render(request, 'create_task.html', {'form': form})
def post(self, request, *args, **kwargs):
form = TaskForm(request.POST)
if form.is_valid():
task = form.save(commit=False)
task = Task(**form.cleaned_data)
task.task_user = request.user
task.save()
messages.add_message(request, messages.INFO, "Task %s was successfully created!" % task.task_title)
return redirect('tasks:user_home', user=request.user)
else:
return render(request, 'create_task.html', {'form': form, 'errors':form.errors})
формы.py
class TaskForm(forms.ModelForm):
task_date=forms.DateField(input_formats="%Y-%m-%d")
class Meta:
model = Task
fields = ['task_title', 'task_description']
ОБНОВЛЕНИЕ: после множества экспериментов и исследований я создал следующее решение:
модели.py
class Task(models.Model):
task_title = models.CharField(verbose_name="Название задачи: ", max_length=150)
task_description = models.TextField(verbose_name="Описание: ", max_length=1000)
task_user = models.ForeignKey('User', on_delete=models.CASCADE)
task_date = models.DateField()
def __str__(self):
return self.task_title
(^^^обратите внимание на отсутствие поля выбора) и forms.py:
def get_today():
return datetime.datetime.now().date()
def get_tomorrow():
return (datetime.datetime.now() + datetime.timedelta(days=1)).date()
TODAY = get_today
TOMORROW = get_tomorrow
DATE_SELECTION = (
(TODAY, "Today"),
(TOMORROW, "Tomorrow"),
)
class TaskForm(forms.ModelForm):
task_date = forms.DateField(input_formats=["%Y-%m-%d"], widget=forms.Select(choices=DATE_SELECTION))
class Meta:
model = Task
fields = ['task_title', 'task_description']
(^^^обратите внимание на виджет выбора, input_formats, который всегда должен быть списком)
TaskForm
вы пытались добавить input_formats в рассматриваемое поле даты? Вот так: docs.djangoproject.com/ ru/2.0/ref/forms/fields/ - person wholevinski   schedule 11.06.2018date.date
, который затем можно было бы вставить в столбецmodels.DateField
. Я предполагаю, что это имело побочный эффект превращения вашего выпадающего списка в текстовое поле? Не уверен, почему. Если это не то, что вы не можете обойти, возможно, стоит просто сделатьstrptime
в вашемpost
прямо перед вызовомform.is_valid
. - person wholevinski   schedule 12.06.2018