首页 文章

如何为Django 's data model (converting from Propel'的YML格式编写此类)

提问于
浏览
1

我正在将当前使用Propel ORM的Web项目转换为django项目 .

我的第一个任务是将模型模式“移植”到django的 .

我已经阅读了django文档,但它们看起来并不够详细 . 举个例子,我如何'移植'在Propel YML模式中定义的(人为)表如下:

demo_ref_country:
    code:             { type: varchar(4), required: true, index: unique }
    name:             { type: varchar(64), required: true, index: unique }
    geog_region_id:   { type: integer, foreignTable: demo_ref_geographic_region, foreignReference: id, required: true, onUpdate: cascade, onDelete: restrict }
    ccy_id:           { type: integer, foreignTable: demo_ref_currency_def, foreignReference: id, required: true, onUpdate: cascade, onDelete: restrict }
    flag_image_path:  { type: varchar(64), required: true, default: ''}
    created_at: ~

    _indexes:

      idx_f1:         [geog_region_id, ccy_id, created_at]

    _uniques:

      idxu_f1_key:    [code, geog_region_id, ccy_id]

到目前为止,这是我的(虚弱)尝试:

class Country(models.Model):
    code = models.CharField(max_length=4)  # Erm, no index on this column .....
    name = models.CharField(max_length=64) # Erm, no index on this column .....
    geog_region_id = models.ForeignKey(GeogRegion)  # Is this correct ? (how about ref integrity constraints ?
    ccy_id = models.ForeignKey(Currency) # Is this correct?
    flag_image_path = models.CharField(max_length=64) # How to set default on this col?
    created_at = models.DateTimeField()    # Will this default to now() ?
    # Don't know how to specify indexes and unique indexes ....

[Edit]

对于那些暗示我是RTFM的人,我理解你的挫败感 . 只是文档对我来说不是很清楚 . 它可能是一种Pythonic文档方式 - 但是来自C背景,我觉得可以改进文档,使其更容易被来自不同语言的人访问 .

举个例子:文档只是说明了ctor中的类名和**选项参数,但没有告诉你可能的选项是什么 .

例如CharField类(max_length = None,[** options])

文档中还有一行提供了允许选项列表,这些选项适用于所有字段类型 .

但是,选项以以下形式提供:

Field.optionname

我不清楚类属性和构造函数参数之间的(显然是隐式的)链接 . 看来如果一个类有一个属性foo,那么这意味着你可以将一个名为foo的参数传递给它的构造函数 . 这种观察对所有Python类都适用吗?

5 回答

  • 1
    Class demo_ref_country(models.Model)
        code= models.CharField(max_length=4, db_index=True, null=False)
        name= models.CharField(max_length=64, db_index=True, null=False)
        geog_region = models.ForeignKey(geographic_region, null=False)
        ccy = models.ForeignKey(Currency_def, null=False)
        flag = models.ImageField(upload_to='path to directory', null=False, default="home")
        created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    
    class Meta:
        unique_together = (code, geog_region, ccy)
    

    您可以设置默认值,db_index paramaeter为相关字段创建索引 . 对于单独的字段,您可以使用unique = True,但是唯一的tahat将一起检查列中的唯一性 .

    更新:首先,我建议你仔细阅读documentatin,因为django给你很多机会,其中一些有一些限制......比如,unique_together选项用 just for django admin . 这意味着如果您创建新记录或通过管理界面对其进行编辑,则会使用它 . 如果您将alsa以其他方式插入数据(如DataModel.objects.create语句),则最好在字段定义中使用uniaue = True,如:

    code= models.CharField(max_length=4, db_index=True, null=False, unique=True)
    

    ForeignKey字段作为默认值是唯一的,因此您无需为它们定义唯一性 .

    Django支持方法覆盖,因此您可以根据需要覆盖模型保存和删除方法 . check it here . Django还允许你编写原始的sql查询you can check it here

    正如我所解释的,独特的一起是django管理功能 . 所以不要忘记将unique = True添加到必填字段 . 独特的一起还允许您定义不同的唯一对,例如;

    unique_together = (('id','code'),('code','ccy','geog_region'))
    

    这意味着,id和代码必须是唯一的 and 代码,ccy和geog_region必须是唯一的

    更新2:在您的问题更新之前......

    你最好从tutorials开始 . 它用很好的例子定义了基础知识 .

    至于doc样式,让我举个例子,但如果你从导师开始,对你来说会更容易......有来自模型结构...... Doc here

    BooleanField
    
    class BooleanField(**options)
    

    定义了数据库字段的基本结构(),它有一些参数作为选项 . 这是部分:

    models.BooleansField()
    

    由于这是一个字段结构,因此可用选项定义为:

    unique
    
    Field.unique
    

    所以,

    models.BooleansField(unique=True)
    

    这是一般用法 . 由于uniqu是所有字段类型都可用的基本选项,因此它被归类为field.unique . 单个字段类型有一些选项可用,例如对称,它是ManyToMany字段选项,被归类为ManyToMany.Symmetrical

    对于queryset

    class QuerySet([model=None])
    

    当你使用一个函数时使用它,但你用它来过滤一个模型,换句话说,编写一个过滤查询来执行...它有一些方法,比如过滤...

    filter(**kwargs)
    

    由于这需要一些kwargs,并且正如我之前所说,这用于过滤您的查询结果,因此kwargs必须是您的模型字段(数据库表字段)喜欢:

    MyModel.objects.filter(id=15)
    

    什么对象在doc中定义,但它是一个帮助您获取相关对象的管理器 .

    Doc包含很好的例子,但你必须从导师开始,这就是我可以建议你的...

  • 1

    为您对其他模型(即外键)的引用自动生成索引 . 换句话说:你的geog_region_id是正确的(但是把它称为geog_region会更好 . )

    您可以使用default field option设置默认值 .

  • 1
    import datetime
    class Country(models.Model):
        code = models.CharField(max_length=4, unique=True) 
        name = models.CharField(max_length=64)
        geog_region = models.ForeignKey(GeogRegion)  
        ccy = models.ForeignKey(Currency, unique=True)
        flag_image_path = models.CharField(max_length=64, default='') 
        created_at = models.DateTimeField(default=datetime.now())
    

    (我不是推进者的专家)

    Django总是试图模仿"cascade on delete"行为,因此无需指定某处 . 默认情况下,所有字段都是必需的,除非另有说明对于datetime字段,请参阅更多选项here . 所有常规字段选项here .

  • 0
    code = models.CharField(max_length=4)  # Erm, no index on this column .....
    name = models.CharField(max_length=64) # Erm, no index on this column .....
    

    您可以为上述两个都传递unique = True关键字参数和值 .

    geog_region_id = models.ForeignKey(GeogRegion)  # Is this correct ? (how about ref integrity constraints ?
    ccy_id = models.ForeignKey(Currency) # Is this correct?
    

    如果在此模型之前定义了 GeogRegionCurrency ,则上述行是正确的 . 否则在模型名称周围加上引号 . 对于例如 models.ForeignKey("GeogRegion") . 见documentation .

    flag_image_path = models.CharField(max_length=64) # How to set default on this col?
    

    简单 . 使用 default = "/foo/bar" 关键字参数和值 .

    created_at = models.DateTimeField()    # Will this default to now() ?
    

    不是自动的 . 你可以做default = datetime.now(记得先 from datetime import datetime ) . 或者,您可以指定auto_now_add = True .

    # Don't know how to specify indexes and unique indexes ....
    

    看看unique_together .

    您会看到我链接到的文档与其他人指出的相同 . 我强烈建议您阅读文档并通过tutorial进行操作 .

  • 1

    我'm sorry, you haven't阅读文档 . 在field reference page上简单搜索 indexuniquedefault 可以准确地显示如何设置这些选项 .

    Edit after comment 我不关心你在括号内使用了多少行 - 所以这个:

    name = models.CharField(unique=True, db_index=True)
    

    与此完全相同:

    name = models.CharField(
              unique=True,
              db_index=True
           )
    

    Django不支持多列主键,但如果您只想要多列唯一约束,请参阅unique_together .

相关问题