美文网首页
Django -- Model

Django -- Model

作者: liaozb1996 | 来源:发表于2018-03-22 23:38 被阅读0次
    Model.jpg
    # myapp/models.py
    from django.db import models
    
    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)
        
        def __str__(self):
            return self.first_name + self.last_name
    
    • Django 会自动添加一个 Primary Key -- id

    # mysite/settings.py
    INSTALLED_APPS = [
        #...
        'myapp',
        #...
    ]
    

    步骤:

    1. myapp/models.py 定义 Model
    2. mysite/settings.pyINSTALLED_APP 添加 APP
    3. $ python manage.py makemigrations (可选)
    4. $ python manage.py migrate

    Fields

    除了表示 Model 之间关系的: ForeignKey, ManyToManyField, OneToOneField 之外,其他 Field 都有一个可选的参数(第一位置),用于指定 Field 的名称,如果省略,则与 Field 变量名相同(下划线将被空格替代)

    first_name = models.CharField("person's first name", max_length=30) # person's first name
    first_name = models.CharField(max_length=30) # first name
    
    • 表示关系的 Field 的第一个参数是 Model Class,所以要指定名称需要使用关键字参数 verbose_name (值的首字母不要大写,Django将在必要时自动转换)

    Field Types

    Field Options

    Private Options
    • model.CharField(): max_length
    Public Options
    • null: False (数据库)
    • blank: False (HTML Form)
    • default: value / callable object
    • unique
    • primary_key = True: 覆盖默认的主键 id
    from django.db import models
    
    class Fruit(models.Model):
        name = models.CharField(max_length=100, primary_key=True)
    
    >>> fruit = Fruit.objects.create(name='Apple')
    >>> fruit.name = 'Pear'
    >>> fruit.save()
    # 主键是只读的,如果修改主键的值并保存,实际上是新创建一个值
    >>> Fruit.objects.values_list('name', flat=True)
    <QuerySet ['Apple', 'Pear']>
    
    • choices: 里面包含有个值的元组的一个可迭代对象
    YEAR_IN_SCHOOL_CHOICES = (
        ('FR', 'Freshman'),  # (value, 'display text')
        ('SO', 'Sophomore'),
        ('JR', 'Junior'),
        ('SR', 'Senior'),
        ('GR', 'Graduate'),
    )
    

    from django.db import models
    
    class Person(models.Model):
        SHIRT_SIZES = (
            ('S', 'Small'),
            ('M', 'Medium'),
            ('L', 'Large'),
        )
        name = models.CharField(max_length=60)
        shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
    

    >>> p = Person(name="Fred Flintstone", shirt_size="L")
    >>> p.save()
    >>> p.shirt_size
    'L'
    >>> p.get_shirt_size_display() # 查看用于显示的值 get_field_display()
    'Large'
    

    common model field option reference

    Relationships

    Many to one: ForeignKeyField

    表示多对一的关系,使用: django.db.models.ForeignKey

    • 习惯:在子属中定义 ForeignKey
    # 一个汽车厂对应多辆汽车
    from django.db import models
    
    class Manufacturer(models.Model):
        # ...
        pass
    
    class Car(models.Model):
        manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)  
        # 习惯:变量名与关联的 Model 相同,使用小写
        # ...
    

    Many-to-one relationship model example.

    Many to Many: ManyToManyField

    简单的多对多关系
    # 一个披萨上可以放多种配料
    # 不同配料可以放在不同披萨上
    from django.db import models
    
    class Topping(models.Model):
        # ...
        pass
    
    class Pizza(models.Model):
        # ...
        toppings = models.ManyToManyField(Topping)
        # 习惯:用复数的变量名(表示多个对象)
        # 只能在任意一个 Model 上定义 ManyToManyField
        # 习惯是放在 HTML Form 中占主要的那个
    
    复杂的多对多关系

    复杂的多对多关系可能会在多对多的关系上定义额外的属性,因此,可以将 “关系” 写成一个独立的 Model(这个 Model 称为中间Model, intermediate model),通过参数 through 指明

    # 乐队与成员之间的关系
    # 一个乐队可以拥有多名成员
    # 一名音乐家可以加入多个乐队
    from django.db import models
    
    class Person(models.Model):
        name = models.CharField(max_length=128)
    
        def __str__(self):
            return self.name
    
    class Group(models.Model):
        name = models.CharField(max_length=128)
        members = models.ManyToManyField(Person, through='Membership')  # through 指明中间 Model
    
        def __str__(self):
            return self.name
    
    class Membership(models.Model):
        # 用 Foreign 指明两个多对多关系的 Model
        person = models.ForeignKey(Person, on_delete=models.CASCADE)
        group = models.ForeignKey(Group, on_delete=models.CASCADE)
        date_joined = models.DateField()
        invite_reason = models.CharField(max_length=64) 
    

    # 对于复杂的多对多关系,必须通过建立 中间Model 来建立多对多关系
    # 因为 中间Model 还需要额外的信息:date_joined, invite_reason  
    # 创建两个人物 ringo, paul
    >>> ringo = Person.objects.create(name="Ringo Starr")
    >>> paul = Person.objects.create(name="Paul McCartney")
    
    # 创建一个乐队 beatles
    >>> beatles = Group.objects.create(name="The Beatles")
    
    # ringo 加入 beatles
    >>> m1 = Membership(person=ringo, group=beatles,
    ...     date_joined=date(1962, 8, 16),
    ...     invite_reason="Needed a new drummer.")
    >>> m1.save()
    
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>]>
    >>> ringo.group_set.all()
    <QuerySet [<Group: The Beatles>]>
    
    # paul 加入 beatles
    >>> m2 = Membership.objects.create(person=paul, group=beatles,
    ...     date_joined=date(1960, 8, 1),
    ...     invite_reason="Wanted to form a band.")
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>
    

    >>> # add, create, set 仅适用于简单的多对多关系,以下操作无效
    >>> # The following statements will not work
    >>> beatles.members.add(john)
    >>> beatles.members.create(name="George Harrison")
    >>> beatles.members.set([john, paul, ringo, george])
    
    >>> # remove 同样无效,应为如果成员不是唯一的(未使用 unique),remove 不知道要移除哪个
    >>> # ringo 再次加入乐队
    >>> Membership.objects.create(person=ringo, group=beatles,
    ...     date_joined=date(1968, 9, 4),
    ...     invite_reason="You've been gone for a month and we miss you.")
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]>
    >>> # This will not work because it cannot tell which membership to remove
    >>> beatles.members.remove(ringo)
    
    >>> # 但是可以使用清空操作: clear
    >>> # Beatles have broken up 乐队解散
    >>> beatles.members.clear()
    >>> # Note that this deletes the intermediate model instances 
    >>> # 同时 Membership 将被删除
    >>> Membership.objects.all()
    <QuerySet []>
    
    • 查询操作跟简单多对多关系一样
    # Find all the groups with a member whose name starts with 'Paul'
    # 查询一个组:其中有一位称为的名字以 Paul 开头
    >>> Group.objects.filter(members__name__startswith='Paul')
    <QuerySet [<Group: The Beatles>]>
    
    # Find all the members of the Beatles that joined after 1 Jan 1961
    # 查询成员:在 The Beatles 乐队,并且是在 1961 年 1 月 1 日后加入
    >>> Person.objects.filter(
    ...     group__name='The Beatles',
    ...     membership__date_joined__gt=date(1961,1,1))
    <QuerySet [<Person: Ringo Starr]>
    
    # 查询 关系中的信息 方式一
    >>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
    >>> ringos_membership.date_joined
    datetime.date(1962, 8, 16)
    >>> ringos_membership.invite_reason
    'Needed a new drummer.'
    
    # 查询 关系中的信息 方式二
    >>> ringos_membership = ringo.membership_set.get(group=beatles)
    >>> ringos_membership.date_joined
    datetime.date(1962, 8, 16)
    >>> ringos_membership.invite_reason
    'Needed a new drummer.'
    

    Many-to-many relationship model example

    One to One: OneToOneField

    一对一的关系多用于继承一个 Model,并且 子Model 中将 父Model 作为 Primary Key

    from django.db import models
    
    class Place(models.Model):
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=80)
    
        def __str__(self):
            return "%s the place" % self.name
    
    class Restaurant(models.Model):
        place = models.OneToOneField(
            Place,
            on_delete=models.CASCADE,
            primary_key=True,
        )
        serves_hot_dogs = models.BooleanField(default=False)
        serves_pizza = models.BooleanField(default=False)
    
        def __str__(self):
            return "%s the restaurant" % self.place.name
    
    class Waiter(models.Model):
        restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
        name = models.CharField(max_length=50)
    
        def __str__(self):
            return "%s the waiter at %s" % (self.name, self.restaurant)
    

    One-to-one relationship model example

    剩下 https://docs.djangoproject.com/en/2.0/topics/db/models/#models-across-files

    相关文章

      网友评论

          本文标题:Django -- Model

          本文链接:https://www.haomeiwen.com/subject/xhuzqftx.html