Models模型(下)
Posted bijian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Models模型(下)相关的知识,希望对你有一定的参考价值。
一、最基本的django模型
1、先看下一个新闻博客的Article模型。这个模型是最基本的django模型,里面包括了各个字段(fields),重写了显示文章对象名字的__str__方法(python内置的),并在Meta选项里给模型命名(verbose name)。建议每个django模型至少包括字段,重写的__str__方法和Meta选项。
from django.db import models from django.contrib.auth.models import User from django.urls import reverse from django.utils.timezone import now # Create your models here. class Article(models.Model): STATUS_CHOICES = ( (‘d‘, ‘草稿‘), (‘p‘, ‘发表‘), ) title = models.CharField(‘标题‘, max_length=200, unique=True) slug = models.SlugField(‘slug‘, max_length=60) body = models.TextField(‘正文‘) pub_date = models.DateTimeField(‘发布时间‘, default=now, null=True) create_date = models.DateTimeField(‘创建时间‘, auto_now_add=True) mod_date = models.DateTimeField(‘修改时间‘, auto_now=True) status = models.CharField(‘文章状态‘, max_length=1, choices=STATUS_CHOICES, default=‘p‘) views = models.PositiveIntegerField(‘浏览量‘, default=0) author = models.ForeignKey(User, verbose_name=‘作者‘, on_delete=models.CASCADE) tags = models.ManyToManyField(‘Tag‘, verbose_name=‘标签集合‘, blank=True) def __str__(self): return self.title class Meta: verbose_name = "article"
2、基础模型很多时候并不能满足需求。试想打算使用django自带的通用视图创建文章,由于通用视图在完成对象创建后需要跳转到文章的absolute_url, 这时需要在模型里加入自定义的get_absolute_url方法。由于希望统计每篇文章浏览次数,还需自定义一个使浏览量自增1的viewed方法,并更新数据表。
def get_absolute_url(self): return reverse(‘blog:article_detail‘, args=[str(self.id)]) def viewed(self): self.views += 1 self.save(update_fields=[‘views‘])
如果希望调用Article.objects.all()按时pub_date降序排列查询结果,可以在Meta里加入ordering选项即可。
class Meta: ordering = [‘-pub_date‘] verbose_name = "article"
二、模型中自定义图片和文件上传路径
Django模型中的ImageField和FileField的upload_to选项是必填项,其存储路径是相对于MEIDA_ROOT而来的。然而可能希望动态定义上传路径,比如把文件上传到每个用户名下的文件夹里,并对上传文件重命名,这时可以定义一个user_directory_path方法。
from django.db import models from django.contrib.auth.models import User import uuid import os # Create your models here. def user_directory_path(instance, filename): ext = filename.split(‘.‘)[-1] filename = ‘{}.{}‘.format(uuid.uuid4().hex[:10], ext) # return the whole path to the file return os.path.join(instance.user.id, "avatar", filename) class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name=‘profile‘) avatar = models.ImageField(upload_to=user_directory_path, verbose_name="头像")
三、Django模型的Manager方法
Django模型自带models.Manager方法,可以简化代码。如下面案例中,可以使用Person.objects.all()查询到所有人,而Person.authors.all和Person.editors.all()只返回所authors和editors。
from django.db import models # Create your models here. class AuthorManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(role=‘A‘) class EditorManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(role=‘E‘) class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) role = models.CharField(max_length=1, choices=((‘A‘, _(‘Author‘)), (‘E‘, _(‘Editor‘)))) objects = models.Manager() authors = AuthorManager() editors = EditorManager()
四、Django模型的save方法重写
在很多应用场景中需要重写django模型的save方法。
from django.db import models import hashlib class UserInfo(models.Model): username = models.CharField("用户名", max_length=64, unique=True) password = models.CharField("密码", max_length=64) uid = models.CharField(verbose_name=‘个人唯一ID‘, max_length=64, unique=True) wx_id = models.CharField(verbose_name="微信ID", max_length=128, blank=True, null=True, db_index=True) def save(self, *args, **kwargs): # 创建用户时,为用户自动生成个人唯一ID if not self.pk: # 存在就更新,不存在就创建 m = hashlib.md5() m.update(self.username.encode(encoding="utf-8")) self.uid = m.hexdigest() super(UserInfo, self).save(*args, **kwargs)
五、完美的Django高级模型结构
from django.db import models from django.urls import reverse # Create your models here. # 自定义Manager方法 class HighRatingManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(rating=‘1‘) class Product(models.Model): # CHOICES选项 RATING_CHOICES = ( ("1", ‘Very good‘), ("2", ‘Good‘), ("3", ‘Bad‘), ) # 数据表字段 name = models.CharField(‘name‘, max_length=30) rating = models.CharField(max_length=1, choices=RATING_CHOICES) # MANAGERS方法 objects = models.Manager() high_rating_products = HighRatingManager() # META类选项 class Meta: verbose_name = ‘product‘ verbose_name_plural = ‘products‘ # __str__方法 def __str__(self): return self.name # 重写save方法 def save(self, *args, **kwargs): pass # 定义绝对路径 def get_absolute_url(self): return reverse(‘product_details‘, kwargs={‘pk‘: self.id}) # 定义其它方法 def do_something(self): pass
以上是关于Models模型(下)的主要内容,如果未能解决你的问题,请参考以下文章
如何从django中具有@property装饰器的模型类序列化函数