【问题标题】:Django Datetime Choice field issueDjango 日期时间选择字段问题
【发布时间】:2018-06-11 18:40:46
【问题描述】:

所以,我对 Django 很陌生,我正在尝试将以下想法付诸实践: 在我的对象创建表单中,我希望用户填写日期字段,以便在对象上放置各种时间戳。问题是我只想让两天可供选择 - 今天和明天。我不想使用 DateTime 字段并让用户手动输入日期,因为它看起来很丑陋并且使用起来不太方便。我决定尝试实现一个选择字段。它渲染得很好,但到目前为止我还没有弄清楚如何让我的表单数据通过有效。我一直在研究 pdb,结果阅读了有关清理/验证方法的信息,但我仍然不知道如何让它工作。 我已经尝试过的: 添加以日期对象和字符串形式返回今天和明天的函数(这里是后者) 错误文本是: 选择一个有效的选项,不是可用的选项之一 我认为它在 clean() 方法期间以某种方式失败。 或者,如果这不是一个合理的想法(可能不是),还有什么替代方案?

models.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}) 

forms.py

class TaskForm(forms.ModelForm):    
    task_date=forms.DateField(input_formats="%Y-%m-%d")
    class Meta:
        model = Task
        fields = ['task_title', 'task_description']

更新: 经过大量的实验和研究,我创建了以下解决方案:

models.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/en/2.0/ref/forms/fields/…
  • 我编辑了我的问题(添加了 forms.py),我把 input_formats 放在那里,现在它不允许我提交表单,说“输入有效日期”,以及我的 html 中的日期字段现在是 text_field
  • 我有一个想法,但是这里已经很晚了,所以我会尝试把它写成代码,明天再回来看看结果
  • 嗯,好吧,所以 input_formats 旨在尝试将您的文本输入转换为 date.date 对象,然后可以将其插入到 models.DateField 列中。我想这有让你的下拉列表成为文本字段的副作用?不知道为什么。如果这不是您无法解决的问题,那么在您致电form.is_valid 之前,在您的post 中执行strptime 可能是值得的。
  • 我回来了,我成功地解决了这个问题,结果实际上看起来相当不错!非常感谢您的意见,它有很大帮助,我现在会更新我的帖子。

标签: django django-models django-validation


【解决方案1】:

更新:经过大量实验和研究,我创建了以下解决方案:

models.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,它必须始终是一个列表)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    相关资源
    最近更新 更多