【问题标题】:data format value changes in database数据库中数据格式值的变化
【发布时间】:2013-06-11 23:06:23
【问题描述】:

forms.py

DATE_INPUT_FORMAT = (
    ('%d/%m/%Y','%m/%d/%Y')
)

class ReportForm(forms.ModelForm):
    manual_date = forms.DateField(input_formats = DATE_INPUT_FORMAT,
                      widget=forms.DateInput(format = '%d/%m/%Y'))  

1.日期格式应根据数据库中的值而改变,如果值在db中,则显示第一种格式,对于无,其他部分正在执行。

2.格式根据情况而变化。

3.我在这里遇到问题,如果输入格式是这个(%m/%d/%Y),在表单发布时,日期的值会交换并保存在数据库中。如果给定的日期是 07/ 06/2013 --> 2013 年 6 月 7 日,在表单发布后,它在字段中被视为 06/07/2013 -->2013 年 7 月 6 日。它无法正常工作。

需要帮助来解决这个问题。

谢谢

【问题讨论】:

  • dateformat 是什么?
  • 我的意思是视图中的局部变量dateformat 是什么?
  • 它是从 1 个表中查询到的值,它包含 1 或 0。如果值为 0,则格式为 dd/mm/yy,对于值 1,格式为 mm/dd/yy
  • ok.. 这种格式dateFormat: ('dd/mm/yy') 不应该改变吗?
  • 不,它没有改变

标签: django django-models django-forms django-views


【解决方案1】:

最简单的解决方案是创建用于呈现表单的工厂:

def ReportFormFactory(date_format):
    class ReportForm(forms.ModelForm):
       manual_date = forms.DateField(
          input_formats=[date_format],
          widget=forms.DateInput(format=date_format)
       )
    return ReturnForm

然后在视野中:

if int(dateformat):
    ReportForm = ReportFormFactory('%m/%d/%Y')
else:
    ReportForm = ReportFormFactory('%d/%m/%Y')

日期应仅在小部件的呈现阶段更改为字符串,在其他地方将它们保留为日期时间或日期对象

【讨论】:

  • ,我收到此错误“异常类型:NameError at /member/when/ 异常值:未定义全局名称'ReportDatetimeForm'”
  • 哪里有 ReportDatetimeForm ?!
  • 对不起dswistowski,我犯了那个错误并清除了,现在我需要的是,在表单发布后输入的日期不应该清除。为此,我添加了模型的实例,即使那样表单发布后数据消失。
  • 你能告诉我在表单发布后显示发布日期吗,也就是说,该字段应该处于更新模式。
  • ,你能告诉我如何使用你的方法在更新模式下显示日期吗?
【解决方案2】:

这是另一种动态更改输入格式的方法

forms.py:

class ReportForm(forms.Form):

    manual_time = forms.TimeField(input_formats = TIME_INPUT_FORMAT,
                      widget=forms.TimeInput(attrs={'size':'8','class':'time_field'}))
    manual_date = forms.DateField(widget=forms.DateInput(
                            attrs={'size':'15', 'id':'datepicker'}))

    def __init__(self, *args, **kwargs):
        # Get the date_format if present in parameters
        date_format = None
        if 'date_format' in kwargs:
            date_format = kwargs.pop('date_format')

        super(ReportForm, self).__init__(*args, **kwargs)
        # Dynamically set input date format
        if date_format:
            self.fields['manual_date'].input_formats = (date_format, )  

views.py

def when(request):
    """To view and save report time and date
    """

    if not 'report_id' in request.session:
        return redirect('incident.views.new_report')
    report_id = request.session['report_id']
    report = Report.objects.get(pk=report_id)
    try:
        settings = Settings.objects.get(user=request.user)
        dateformat = settings.date_format
        timeformat = settings.time_format
    except:
        dateformat = False
        timeformat = False
    date = None
    time = None
    if not report.manual_date:
        report.manual_date = datetime.datetime.now()

    if not report.manual_time:
        report.manual_time = datetime.datetime.now()
    manual_date = datetime.datetime.now()

    if int(dateformat):
        date_format = '%m/%d/%Y'    
        datelabel = "Date(mm/dd/yyyy)"
        createddate = report.created_date_time.strftime('%b %d %Y')
    else:
        date_format = '%d/%m/%Y'
        datelabel = "Date(dd/mm/yyyy)"
        createddate = report.created_date_time.strftime('%d %b %Y')

    date = report.manual_date.strftime(date_format)

    if int(timeformat):
        time = report.manual_time.strftime('%H:%M')
        timelabel = "Time(24hour)"
        createdtime = report.created_date_time.strftime('%H:%M')
    else:
        time = report.manual_time.strftime('%I:%M %p')
        timelabel = "Time(12hour)"
        createdtime = report.created_date_time.strftime('%I:%M %p')

    if request.method == 'POST':

        reportform = ReportForm(request.POST, date_format=date_format)
        if reportform.is_valid():
            report.manual_date = reportform.cleaned_data['manual_data']
            report.manual_time = reportform.cleaned_data['manual_time']
            report.user = request.user
            report.save()

            if not 'next' in request.POST:
                return redirect('incident.views.report_confirm')
            return redirect('incident.views.media')
    else:    
        reportform = ReportForm(instance=report, initial={'manual_date':date, 'manual_time':time})

    leftbar = common_leftbar(request, report_id)
    return render_to_response('incident/when.html',
                               {
                                'newreport_menu': True,
                                'when_tab': True,
                                'reportform': reportform,
                                'datelabel':datelabel,
                                'timelabel':timelabel,
                                'createddate':createddate,
                                'createdtime':createdtime,
                                'incident': report,
                                'leftbar':leftbar
                                 },
                                   context_instance=RequestContext(request))

创建表单时动态更改 DateField 的input_formats 属性的关键。因此,当您提交表单时,您应该传递 date_format 并且默认的 DateField 应该可以很好地转换您的日期。您将不得不将此代码改编为您的代码,因为我在上面的代码中假设了一些内容。

【讨论】:

  • 您需要在您的代码中调整我的代码。所以我的代码可能无法直接工作。确保您设置了正确的 date_format 变量,它必须是“%d/%m/%Y”或“%m/%d/%Y”。因此,与其做我所做的事情,不如根据您的报告条件传递其中一个,看看它是否有效。
  • 检查我更新的要点,看看是否有效:gist.github.com/maulik13/088c022c9a25fd36a218 我修改了视图。
  • ,我试过你的代码,表单没有发布,问题是如果我点击下一个按钮,它应该保存并重定向到下一页,它留在同一页面。
  • 提交表单时是否收到验证错误?您是否在页面中打印这些错误?
  • 如果您提交的表单进入 if request.method == "POST" 条件,则重定向和此条件之间的唯一内容是 is_valid() 方法。如果在 if 条件中插入 assert False 会发生什么?
【解决方案3】:

我认为你需要继承 DateField 并覆盖 strptime 方法来做你想做的事。

class MyDateField(forms.DateField):
    def strptime(self, value, format):
        # Ignore format and continue by your dateformat
        if int(dateformat):
            date = datetime.datetime.strptime(force_str(value), '%m/%d/%Y').date()
        else:
            date = datetime.datetime.strptime(force_str(value), '%d/%m/%Y').date()
        # Output for debugging
        print "Raw input: '%s', dateformat: %s, date: %s" % (value, dateformat, date)
        return date

class ReportForm(forms.ModelForm):
    manual_date = MyDateField(widget=forms.DateInput(format='%d/%m/%Y',
        attrs='size':'15', 'id':'datepicker', 'readonly':'readonly'}))

我不知道dateformat标志是从哪里来的,所以可能会引起一些麻烦。

注意:我刚刚注意到该小部件是只读的。为什么要将其添加到表单中?如果只在模板中显示日期会简单得多。

注意2:有几件事情你应该注意:你有d/m/Y在你的小部件和日期选择器中设置了格式,这些可能会导致麻烦。您应该在表单中将日期实例作为初始值传递,这样会更好。

【讨论】:

  • dateformat 标志来自 dateformat 表,如果值为 1,则输入格式应为 mm/dd/yyyy,0 为 dd/mm/yyyy 格式。我尝试了您的回答,抱歉,问题仍然存在他们的。
  • 在这里我正在解释问题,以便很容易找到我做错了什么。虽然以(dd/mm/yyyy)格式输入没有问题,但以(mm/dd/yyyy)格式输入,在数据库格式中得到交换和保存。 /eg.如果数据库中的输入是(05/07/2013,格式为 mm/dd/yyyy),则另存为(07/05/2013)日期和月份会互换。所以请告诉我如何将两种输入格式保存在仅此格式(dd/mm/yyyy)
  • 这个解决方案适用于我尝试的一个小例子。就我而言,我可以可靠地将 mm/dd/yyyy 和 dd/mm/yyyy 格式保存在数据库中。关键是您的日期格式应该在 MyDateField 和您的视图中匹配。您是否尝试过精简代码以专注于日期?
  • Maulik,我现在也试过了,在表格中使用它之后,对于 mm/dd/yyyy 它工作正常,但对于 dd/mm/yyyy 正在发生同样的问题。你能告诉我如何以一种格式将两种格式保存在数据库中。因为在保存 2013 年 2 月 5 日的日期时,可以交换日期和月份并保存在数据库中。如果没有发生这种情况,我的问题肯定会得到解决。我正在寻找它,但使用没有成功,请提供您的答案,将数据库中的两种格式保存为 yyyy-mm-dd 格式。
  • @user2086641 你应该尽量避免在保存时这样做。基本问题是从字符串数据到 python 对象的转换。这是在表单字段定义中完成的。
【解决方案4】:

啊,旧的日期格式问题。您是否考虑过以 [时间戳格式[(Are unix timestamps the best way to store timestamps?) 存储所有日期,然后在显示/保存时正确格式化它们。

我建议您始终以某种格式显示日期,并确保日期以相同格式从视图中返回。对于输入表单,提供多样性是不值得的。

【讨论】:

  • 这是一个 Django 应用程序 - 使用 Django DateField 类将日期存储在数据库中,该类处理与字符串的转换。无需手动处理此问题 - 应该按照我的回答正确配置 Django。
【解决方案5】:

您应该依靠 Django > 1.2 功能来本地化日期格式,而不是重新发明轮子。 Django 以本地化格式处理输出日期,以及处理带有本地化日期的表单提交。你只需要让用户能够设置他/她想要的语言环境,Django 就会自己处理不同的格式。 https://docs.djangoproject.com/en/1.4/topics/i18n/formatting/

【讨论】:

    【解决方案6】:

    试试你的代码是否更清晰:

    reportform = ReportForm(request.POST or None,
                            instance=report,
                            initial={'manual_date':date, 'manual_time':time})
    if reportform.is_valid():
        report = reportform.save(commit=False)
        report.user = request.user
        report.save()
    

    保存表单后发送给客户的格式是什么?

    【讨论】:

      猜你喜欢
      • 2014-07-19
      • 2019-04-14
      • 2017-12-17
      • 2019-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 2011-10-14
      相关资源
      最近更新 更多