Проблема с полем Django Datetime Choice

Итак, я новичок в 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, который всегда должен быть списком)


person vadim_v    schedule 11.06.2018    source источник
comment
В вашем TaskForm вы пытались добавить input_formats в рассматриваемое поле даты? Вот так: docs.djangoproject.com/ ru/2.0/ref/forms/fields/   -  person wholevinski    schedule 11.06.2018
comment
Я отредактировал свой вопрос (добавил forms.py) и поместил туда input_formats, теперь он не позволяет мне отправить форму, говорит, введите действительную дату, а поле даты в моем html теперь является текстовым полем   -  person vadim_v    schedule 11.06.2018
comment
У меня есть идея, но здесь уже довольно поздно, поэтому я попытаюсь реализовать ее в коде и вернусь сюда завтра с результатами.   -  person vadim_v    schedule 11.06.2018
comment
Хм, хорошо, так что input_formats предназначался для того, чтобы попытаться преобразовать вводимый текст в объект date.date, который затем можно было бы вставить в столбец models.DateField. Я предполагаю, что это имело побочный эффект превращения вашего выпадающего списка в текстовое поле? Не уверен, почему. Если это не то, что вы не можете обойти, возможно, стоит просто сделать strptime в вашем post прямо перед вызовом form.is_valid.   -  person wholevinski    schedule 12.06.2018
comment
Я вернулся, и я успешно поработал над проблемой, и в результате это выглядит довольно хорошо! Большое спасибо за ваш вклад, это очень помогло, я обновлю свой пост сейчас.   -  person vadim_v    schedule 12.06.2018


Ответы (1)


ОБНОВЛЕНИЕ: после множества экспериментов и исследований я создал следующее решение:

модели.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, который всегда должен быть списком)

person vadim_v    schedule 12.06.2018