django model 定义、统计、 高阶用法,form相关(字段加密、singal、customManager等),字段校验,电话正则表达式

 

pk使用uuid,字段校验

models.py

import uuid
from django.core.validators import RegexValidator
from django.db import models

class Customer(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255)
    birthday = models.DateField()
    phone_no = models.CharField(
        max_length=11,
        validators=[RegexValidator(r"^[0-9]{11}$", "11桁の数字を入力してください。")],
        blank=True,
    )

    class Meta:
        db_table = "Customer"

 

 

 

 

Django - Update model field based on another field

class Item(models.Model):
    name = models.CharField(max_length=40)
    default_price = models.DecimalField(max_digits=6, decimal_places=2, default=50)

    def __unicode__(self):
        return self.name

class SaleDetail(models.Model):
    item = models.ForeignKey(Item)
    deposit = models.ForeignKey(Deposit)
    quantity = models.PositiveIntegerField()
    entered_unit_price = models.DecimalField(max_digits=6, decimal_places=2, default=None)
    sale = models.ForeignKey(Sale)

    @property
    def unit_price(self, value):
        if self.entered_unit_price is None:
            return self.item.default_price
        else:
            return self.entered_unit_price

    @unit_price.setter
    def unit_price(self, value):
        self.entered_unit_price = value

Then use it like so:

print(sd.unit_price)
sd.unit_price = 500 
sd.save()

 

更好点的用法

 check if there is a pk. If the pk is None, we know that the SaleDetail is new. Then, we see if there is a unit_price. If there is not a unit_price, we set it to the Item.default_price.

 

class Item(models.Model):
    name = models.CharField(max_length=40)
    default_price = models.DecimalField(max_digits=6, decimal_places=2, default=50)

    def __unicode__(self):
        return self.name


class SaleDetail(models.Model):
    item = models.ForeignKey(Item)
    deposit = models.ForeignKey(Deposit)
    quantity = models.PositiveIntegerField()
    unit_price = models.DecimalField(max_digits=6, decimal_places=2)
    sale = models.ForeignKey(Sale)

    def save(self, *args, **kwargs):
        # Make sure this is the first save (pk should be None) and there is no unit_price set
        if self.pk is None and not self.unit_price:
            self.unit_price = self.item.default_price
        elif not self.unit_price:
            self.unit_price = self.item.default_price

        # Call the original save method
        super(SaleDetail, self).save(*args, **kwargs)

 

关于signal:

This calls  post_save 信号会被调用

user = User.objects.get(id=1) 
user.username='edited_username' 
user.save()

This does not call post_save 这种写法,写好不会被调用

User.objects.filter(id=1).update(username='edited_username')

学习signal:https://simpleisbetterthancomplex.com/tutorial/2016/07/28/how-to-create-django-signals.html


深度定制django model:定制managerhttps://docs.djangoproject.com/en/3.1/topics/db/managers/

hidden隐藏字段

Change a Django form field to a hidden field

 

form里的内容用__dict__输出。

model.xxx 可以提取数据

从dict提取数据不能用 dict.xx 而是用 dict.get('xx')

            print(form.instance.status)
            print(form.data.get('status','defaultvalue'))
            print(form.__dict__)

 

 

>2
>2
>{'instance': <KhPeriod: 临时考核112>, '_validate_unique': True, 'is_bound': True, 'data': <QueryDict: {'csrfmiddlewaretoken': ['US7oLRjAiTtBPCD3QEyVSjgTXd3j0cXSEvtJnK4P58sjtHEZ3Jqa6G9swTgjIgab'], 'kaohename': ['临时考核112'], 'status': ['2']}>, 'files': {}, 'auto_id': 'id_%s', 'initial': {'id': 20211, 'kaohename': '临时考核11', 'status': '2'}, 'error_class': <class 'django.forms.utils.ErrorList'>, 'label_suffix': ':', 'empty_permitted': False, '_errors': {}, 'fields': OrderedDict([('kaohename', <django.forms.fields.CharField object at 0x000002139692CA58>), ('status', <django.forms.fields.TypedChoiceField object at 0x000002139692CCC0>)]), '_bound_fields_cache': {'status': <django.forms.boundfield.BoundField object at 0x0000021396AC37B8>}, 'renderer': <django.forms.renderers.DjangoTemplates object at 0x0000021396AD43C8>, 'cleaned_data': {'kaohename': '临时考核112', 'status': '2'}}

 

一、限制数据的方式
data = list(Sale.objects.all())[:100]  最差用法

data = Sale.objects.all()[:100]        较好的用法

二、case  when 的条件统计

from django.contrib.auth.models import User
from django.db.models import Count, F
User.objects.aggregate(
    total_users=Count('id'),
    total_active_users=Count('id', filter=F('is_active')),
)
三、定义
# All 3 are equivalent!  三种定义字段方式相同
full_name = models.CharField(max_length=100)
full_name = models.CharField('full name', max_length=100)
full_name = models.CharField(verbose_name='full name', max_length=100)
四、关联foreign查询
class University(models.Model):
    full_name = models.CharField(    max_length=100,    )
class Student(models.Model): # new
    first_name = models.CharField('first name', max_length=30)
    last_name = models.CharField('last name', max_length=30)
    university = models.ForeignKey(
        University,
        on_delete=models.CASCADE,
        related_name='students',
        related_query_name='person',
    )

    class Meta: # new
        indexes = [models.Index(fields=['first_name'])]
        ordering = ['-first_name']
        verbose_name = 'Student'
 

以上的model,默认的查询方式:

dartmouth = University.objects.get(full_name='Dartmouth')
dartmouth.student_set.all() # returns all students at Dartmouth
University.objects.filter(student__first_name='william') # returns all University students named William

 

设定related_name和query_name后
yale = University.objects.get(full_name='Yale')
yale.students.all() # returns all students at Yale
University.objects.filter(person__first_name='ashley') # returns all University students named Ashley

 以上,注意 Meta可以定义默认的order和indexes, 这个以前没注意过



posted @ 2020-10-16 11:01  花生与酒  阅读(182)  评论(0编辑  收藏  举报