《Django 5 By Example》学习第 20 天,p551-p560 总结,总计 10 页。
一、技术总结
1.custom model field
(1)示例
courses/fields.py
python
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
class OrderField(models.PositiveIntegerField):
def __init__(self, for_fields=None, *args, **kwargs):
self.for_fields = for_fields
super().__init__(*args, **kwargs)
def pre_save(self, model_instance, add):
if getattr(model_instance, self.attname) is None:
# no current value
try:
qs = self.model.objects.all()
if self.for_fields:
query = {
field: getattr(model_instance, field)
for field in self.for_fields
}
qs = qs.filter(**query)
# get the order of the last item
last_item = qs.latest(self.attname)
value = getattr(last_item, self.attname) + 1
except ObjectDoesNotExist:
value = 0
setattr(model_instance, self.attname, value)
return value
else:
return super().pre_save(model_instance, add)
courses/models.py:
python
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from .fields import OrderField
# Create your models here.
class Subject(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
class Meta:
ordering = ['title']
def __str__(self):
return self.title
class Course(models.Model):
owner = models.ForeignKey(User, related_name='courses_created', on_delete=models.CASCADE)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE, related_name='courses')
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
overview = models.TextField()
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['created']
def __str__(self):
return self.title
class Module(models.Model):
course = models.ForeignKey(
Course, related_name='modules', on_delete=models.CASCADE
)
title = models.CharField(max_length=200)
description = models.TextField(blank=True)
order = OrderField(blank=True, for_fields=['course'])
class Meta:
ordering = ['order']
def __str__(self):
return f'{self.order}. {self.title}'
class Content(models.Model):
module = models.ForeignKey(Module, related_name="contents", on_delete=models.CASCADE)
content_type = models.ForeignKey(
ContentType,
on_delete=models.CASCADE,
limit_choices_to={
'model__in': ('text', 'video', 'image', 'file')
}
)
object_id = models.PositiveIntegerField()
item = GenericForeignKey('content_type', 'object_id')
order = OrderField(blank=True, for_fields=['module'])
class Meta:
ordering = ['order']
class ItemBase(models.Model):
owner = models.ForeignKey(User, related_name='%(class)s_related', on_delete=models.CASCADE)
title = models.CharField(max_length=250)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
# 如果不设置 abstract = True 会有什么影响?
abstract = True
def __str__(self):
return self.title
class Text(ItemBase):
content = models.TextField()
class File(ItemBase):
file = models.FileField(upload_to='files')
class Image(ItemBase):
file = models.ImageField(upload_to='images')
class Video(ItemBase):
url = models.URLField()
二、英语总结(生词:1)
1.in respect of
也写作 with respect to,意思是"in connection with something(与xxx有关的)"。
python
class Content(models.Model):
# ...
order = OrderField(blank=True, for_fields=['module'])
p557, This time, you specify that the order is calculated with respect to the module field(这一次,指定根据 module 字段计算顺序)。
三、其它
今天也没有什么想说的。
四、参考资料
1. 编程
(1) Antonio Melé,《Django 5 By Example》:https://book.douban.com/subject/37007362/
2. 英语
(1) Etymology Dictionary:https://www.etymonline.com
(2) Cambridge Dictionary:https://dictionary.cambridge.org
欢迎搜索及关注:编程人(a_codists)