django模型层之models入门篇(Relationship fields)

先看下models结构:

# tournament/models.py
from django.db import models

class Club(models.Model):
    region_choices = [
        ('E', 'East'),
        ('W', 'West'),
    ]
    name = models.CharField(max_length=50)
    region = models.CharField(max_length=20, choices=region_choices)
    desc = models.TextField(max_length=1000, null=True, blank=True)

    class Meta:
        verbose_name = "俱乐部"
        verbose_name_plural =verbose_name

    def __str__(self):
        return self.name

class Season(models.Model):
    name = models.CharField("赛季名称", max_length=100)
    start_time = models.DateTimeField("赛季开始时间")
    end_time = models.DateTimeField("赛季结束时间")

    class Meta:
        verbose_name = "赛季"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Player(models.Model):
    name = models.CharField(max_length=50)
    age = models.IntegerField()
    club = models.ForeignKey(Club, on_delete=models.CASCADE, null=True)
    salary = models.CharField(max_length=30)
    desc = models.TextField(max_length=1000)

    class Meta:
        verbose_name = "球员"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class PlayerData(models.Model):
    player = models.OneToOneField(Player, on_delete=models.CASCADE)
    season = models.ForeignKey(Season, on_delete=models.CASCADE)
    average_score = models.FloatField("平均得分", max_length=10)
    average_assist = models.FloatField("平均助攻", max_length=10)
    average_rebound = models.FloatField("平均篮板", max_length=10)

    class Meta:
        verbose_name = "球员赛季数据"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "%.2f分%.2f助攻%.2f篮板" %(self.average_score, self.average_assist, self.average_rebound)

class News(models.Model):
    title = models.CharField(max_length=150)
    content = models.TextField(max_length=2000)
    players = models.ManyToManyField(Player)
    create_time = models.DateTimeField()
    comment = models.ForeignKey('comment.Comment', on_delete=models.CASCADE)

    class Meta:
        verbose_name = "新闻"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.title
# comment/models.py
from django.db import models

class Comment(models.Model):
    content = models.CharField(max_length=200)
    create_time = models.DateTimeField()
    sub_content = models.ForeignKey('self', on_delete=models.CASCADE)

    class Meta:
        verbose_name = "评论"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.content

 

看下数据库中生成的表结构

 

tournament_club表

 

tournament_season表

 

 

 

tournament_player表

 

tournament_playerdata表

 

 

 

comment_comment表

 

tournament_news表

 

tournament_news_players表

 

几个注意的点:

1、如果是自己关联自己,可以使用self,如上面的comment中,评论可以嵌套评论,可以如此设计

models.ForeignKey('self', on_delete=models.CASCADE)

 

2、如果要关联其他app中的model,可以使用'app.model',而不是去导入,这样可能会引起一些问题,如上面的news中关联comment

 

3、关于on_delete

  1)  on_delete=models.CASCADE 表示级联删除,当关联表(子表)中的数据删除时,与其相对应的外键(父表)中的数据也删除

  例如:上述中club表中定义了两个球队Lakers和warriors,player表中定义了四个球员LeBron James、Davis(关联到Lakers)、Curry、Kely(关联到warriors),此时删除club表中的warrriors后,player表中的Curry、Kely都会被删除

 

  2)on_delete=SET_NULL  删除关联数据(子表),与之关联的值设置默认值为null(父表中),这个前提需要父表中的字段可以为空即 null=True

  

  3)on_delete=SET_DEFAULT 设置默认值,删除子表字段时,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值

 

  4)on_delete=PROTECT 保护模式,如采用这个方法,在删除关联数据时会抛出ProtectError错误

 

4、ForeignKey.related_name 和   ForeignKey.related_query_name

  首先在club表和player表中加入几条数据

  

 

   

 

   然后查询:

  

 

   接下来,先修改下Player的model

  

club = models.ForeignKey(Club, on_delete=models.CASCADE, null=True, related_name='players', related_query_name='p')

  然后执行查询

  

 

posted @ 2022-12-20 22:05  战术鬼才  阅读(110)  评论(0编辑  收藏  举报