zoukankan      html  css  js  c++  java
  • 【Django总结】Django的时间字段DateTimeField

    一. Django的时间字段DateTimeField

      创建django的model时,有DateTimeField、DateField和TimeField三种类型可以用来创建日期字段,其值分别对应着datetime()、date()、time()三中对象。这三个field有着相同的参数auto_now和auto_now_add,表面上看起来很easy,但实际使用中很容易出错,下面是一些注意点。

    <1>DateTimeField.auto_now

      这个参数的默认值为false,设置为true时,能够在保存该字段时,将其值设置为当前时间,并且每次修改model,都会自动更新。因此这个参数在需要存储“最后修改时间”的场景下,十分方便。需要注意的是,设置该参数为true时,并不简单地意味着字段的默认值为当前时间,而是指字段会被“强制”更新到当前时间,你无法程序中手动为字段赋值;如果使用django再带的admin管理器,那么该字段在admin中是只读的。

    <2>DateTimeField.auto_now_add

      这个参数的默认值也为False,设置为True时,会在model对象第一次被创建时,将字段的值设置为创建时的时间,以后修改对象时,字段的值不会再更新。该属性通常被用在存储“创建时间”的场景下。与auto_now类似,auto_now_add也具有强制性,一旦被设置为True,就无法在程序中手动为字段赋值,在admin中字段也会成为只读的。

    <3>admin中的日期时间字段

      auto_now和auto_now_add被设置为True后,这样做会导致字段成为editable=False和blank=True的状态。editable=False将导致字段不会被呈现在admin中,blank=Ture表示允许在表单中不输入值。此时,如果在admin的fields或fieldset中强行加入该日期时间字段,那么程序会报错,admin无法打开;如果在admin中修改对象时,想要看到日期和时间,可以将日期时间字段添加到admin类的readonly_fields中:

    二. Django的外键字段ForeignKey

    有两个数据模型栏目模型和文章模型ArticleColumn和ArticlePost

    ArticleColumn:

    class ArticleColumn(models.Model):
        # 用户与栏目是“一对多”关系,所以用ForeignKey,一个用户可以设置多个栏目,此处的user字段对应实际表中的user_id,来自于User表中主键
        user = models.ForeignKey(User, related_name='article_column')
        column = models.CharField(max_length=100)
        created = models.DateTimeField(auto_now_add=True)

    ArticlePost:

    复制代码
    class ArticlePost(models.Model):
    
        author = models.ForeignKey(User, related_name='article')
        title = models.CharField(max_length=200)
        slug = models.SlugField(max_length=500)
        column = models.ForeignKey(ArticleColumn, related_name='article_column')
        body = models.TextField()
        created = models.DateTimeField(default=timezone.now())
        updated = models.DateTimeField(auto_now_add=True)
        # media/%Y%m%d/为图片的真实放置路径,因为settings中已经配置了MEDIA_ROOT为media文件夹,blank=True允许表单的该字段对应值为空,意思是非必填字段
        avatar = models.ImageField(upload_to='%Y%m%d/', blank=True)
    复制代码

    可以看到在ArticlePost模型中有一个字段为column,且类型为ForeignKey,意思是外键,代表的是“多对一”的关系,第一个参数ArticleColumn是对应的模型名称,related_name为反查时的关联名称。

    多对一指的是,多个文章可以对应一个栏目,比如有10篇文章都是属于django栏目的(当然一个文章也可以对应多个栏目,这样就是多对多关系了:ManyToManyField,此处我们设计不存在这种情况),

    有了外键关系后,那如何去查询某篇文章对应的所属栏目呢?

    article = ArticlePost.objects.get(id=150)
    
    article.column

     如果不使用外键关系,想查询某篇文章对应的所属栏目呢?

    复制代码
    # 获取该文章对象
    article = ArticlePost.objects.get(id=150)
    # 找到该文章对象对应的column_id,column_id这一列就是因为ArticlePost模型中有column字段且将ArticleColumn作为外键,所以将ArticleColumn模型对应表中的主键id的值作为column_id的值,将列名命名为column_id
    article.column_id
    # 根据上面查出来的id找到该栏目对象
    column = ArticleColumn.objects.get(id=article.column_id)
    # 输出栏目名称
    column.column
    复制代码

    那怎么反查某个栏目下有多少文章呢?

    复制代码
    # 查询出叫django的栏目
    column = ArticleColumn.objects.get(column='django')
    # 通过column这个实例.article_column.all(),查询出该栏目下的所有文章,article_column就是在ArticlePost模型中的related_name的值
    column.article_column.all()
    # 反查django这个栏目下title中包含'list'字符串的文章
    column.article_column.filter(title__contains='list')
    class YourAdmin(admin.ModelAdmin):
        readonly_fields = ('save_date', 'mod_date',)
    admin.site.register(Tag, YourAdmin)

    <4>如何将创建时间设置为“默认当前”并且可修改

      那么问题来了。实际场景中,往往既希望在对象的创建时间默认被设置为当前值,又希望能在日后修改它。怎么实现这种需求呢?

    django中所有的model字段都拥有一个default参数,用来给字段设置默认值。可以用default=timezone.now来替换auto_now=True或auto_now_add=True。timezone.now对应着django.utils.timezone.now(),因此需要写成类似下面的形式

    from django.db import models
    import django.utils.timezone as timezone
    class Doc(models.Model):
        add_date = models.DateTimeField('保存日期',default = timezone.now)
        mod_date = models.DateTimeField('最后修改日期', auto_now = True)

      html页面从数据库中读出DateTimeField字段时,显示的时间格式和数据库中存放的格式不一致,比如数据库字段内容为2016-06-03 13:00:00,但是页面显示的却是Apr. 03, 2016, 1 p.m.

    为了页面和数据库中显示一致,需要在页面格式化时间,需要添加<td>{{ infor.updatetime|date:"Y-m-d H:i:s" }}</td> 类似的过滤器。刷新页面,即可正常显示。

    作者:gtea 博客地址:https://www.cnblogs.com/gtea
  • 相关阅读:
    AngularJS(17)-Angular小程序
    AngularJS(16)-路由
    AngularJS(15)-依赖注入
    AngularJS(14)-动画
    AngularJS(13)-包含
    AngularJS(12)-BootStrap集成
    AngularJS(11)-API
    AngularJS(10)-数据验证
    Mysql 备份和恢复.sql文件,导入.csv文件
    Mysql group_concat()
  • 原文地址:https://www.cnblogs.com/gtea/p/12965976.html
Copyright © 2011-2022 走看看