Django 08.15

1.一对一

#models.py:
 class UserInfo(models.Model):
	name = models.CharField(max_length=32,null=True)
    age = models.InterField(null=True)
        
class Private(models.Model):
	salary = models.CharField(max_length=32,null=True)
    sp = models.OneToOneField("UserInfo",null=True)
        
OneToOneField:一对一,默认要求该字段必须是唯一的外键关系(unique)
    
#views.py
from home impoort models
models.UserInfo.objects.create(name="zekai", age=18)
models.Private.objects.create(salary=5000,sp_id=1)
    
def test(request):
    #从母表查询子表中的数据
    ## 查询一下name='zekai'的这条数据所对应的的salary
    
    res = models.UserInfo.objects.filter(name="zekai").first()
    #子表表名小写,子表字段名
    print(res.private.salary)
    
    #从子表查询母表中的数据
    ##查询一下salary = 5000的这个数据所对应的的用户的信息
    res = models.Private.objects.filter(salary=5000).first()
    #关联的字段名,母表的字段名
    print(res.sp.name,res.sp.age)

2.多对多

#models.py
class Boy(models.Model):
    bname = models.CharField(max_length=32null=True)
    
class Girl(models.Model):
    gname = models.CharField(max_length=32,null=True)
    
class Boy2Girl(models.Model):
    b = models.ForeignKey("Boy",null=True)
    g = models.ForeignKey("Girl",null=True)
    
    class Meta:
        ##联合唯一索引
        unique_together = {
            ('b','g')
        }
        
        
     class Meta:
        ##联合索引
        index_together = [
            ('b','g')
        ]
        
#views.py
boyinfo = [
    models.Boy(bname="雷俊"),
    models.Boy(banme="雷鸣"),
    models.Boy(bname="雷震子"),
    models.Boy(bname="雷锋"),
    models.Boy(bname="雷军"),
]
models.Boy.objects.bulk_create(boyinfo)

grilinfo = [
    models.Girl(gname="真真"),
    models.Girl(gname="连连"),
    models.Girl(gname="爱爱"),
    models.Girl(gname="凤姐"),
    models.Girl(gname="乔碧萝"),
]
models.Girl.objects.bulk_create(girlinfo)

b2ginfo = [
    models.Boy2Girl(b_id=1,g_id=1),
    models.Boy2Girl(b_id=1,g_id=2),
    models.Boy2Girl(b_id=1,g_id=3),
    models.Boy2Girl(b_id=1,g_id=5),
    models.Boy2Girl(b_id=2,g_id=4),
    models.Boy2Girl(b_id=2,g_id=5),
]
models.Boy2Girl.objects.bulk_create(b2ginfo)

#需求: 查找一下和雷俊约会的姑娘
#方法1:
res = models.BOy,objects.filter(bname="雷俊").first()
love_list = res.boy2girl_set.all()
for lover in love_list:
    print(lover.g.gname)
    
#2.方法2:
res = models.Boy2Girl.objects.filter(b__bname="雷俊").all()
for lover in love_list:
    print(lover.g.gname)
    
#3.方法3:
res = models.Boy2Girl.objects.filter(b__bname="雷俊").values('g__gname').all()
manytomanyfiled
#models.py:
class Boy(models.Model):
	banme = models.CharField(max_length=32,null=True)
	g = models.ManyToManyField('Girl',null=True)
	
class Girl(models.Model):
	gname = models.CharField(max_length=32,null=True)
	
res = models.Boy.objects.filter(bname="雷俊").first()

##添加:
res.g.add(1)
res.g.add(2,3)

##删除:
res.g.remove(3)

##查询:
res = models.Boy.objects.filter(banme="雷俊).first()
print(res.g.all())

##清除:
res.g.clear() ##清空所有记录

区别:
	第一种方式比较的灵活,自己可以添加任意的字段;
	第二种方式比较死板,只能生成两个字段,业务扩展时,就需要重新打破重来;推荐使用地中方式.

3.表中的数据类型

数字 mysql ORM
tinyint 不存在
smallint SmallIntegerField
mediumintint 不存在
int(unsigned) IntergerField | PositiveIntegerField
bigint BigIntergerField | PositiveBigIntergerField
decimal DecimalField
float FloatField
double 不存在
字符串 char 不存在
varchar CharField
text TextField
时间日期 date DateField
datetime DateTimeField
Django admin 数据类型中:

EmailField(CharField):
	- 字符串类型,Django Admin以及ModelForm中提供验证机制
IPAddressField(Field):
	- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
			GenericIPAddressField(Field)
	- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
	- 参数:
protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
URLField(CharField)
	- 字符串类型,Django Admin以及ModelForm中提供验证 URL
SlugField(CharField)
	- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
CommaSeparatedIntegerField(CharField)
	- 字符串类型,格式必须为逗号分割的数字
UUIDField(Field)
	- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
FilePathField(Field)
	- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
	- 参数:
	path,                      文件夹路径
	match=None,                正则匹配
	recursive=False,           递归下面的文件夹
	allow_files=True,          允许文件
	allow_folders=False,       允许文件夹
FileField(Field)
	- 字符串,路径保存在数据库,文件上传到指定目录
	- 参数:
	upload_to = ""      上传文件的保存路径
	storage = None      存储组件,默认				django.core.files.storage.FileSystemStorage
ImageField(FileField)
	- 字符串,路径保存在数据库,文件上传到指定目录
	- 参数:
	upload_to = ""      上传文件的保存路径
	storage = None      存储组件,默认			django.core.files.storage.FileSystemStorage
width_field=None,   上传图片的高度保存的数据库字段名(字符串)
height_field=None   上传图片的宽度保存的数据库字段名(字符串)


参数:(掌握)
null                数据库中字段是否可以为空
db_column           数据库中字段的列名
default             数据库中字段的默认值
primary_key         数据库中字段是否为主键
db_index            数据库中字段是否可以建立索引
unique              数据库中字段是否可以建立唯一索引

django admin 参数:	
			  verbose_name          Admin中显示的字段名称
				blank               Admin中是否允许用户输入为空
				editable            Admin中是否可以编辑
				help_text           Admin中该字段的提示信息
				choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
如:{'null': "不能为空.", 'invalid': '格式错误'}
validators          
自定义错误验证(列表类型),从而定制想要的验证规则
from django.core.validators import RegexValidator
from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
									MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
如:
test = models.CharField(
		max_length=32,
		error_messages={
		'c1': '优先错信息1',
		'c2': '优先错信息2',
		'c3': '优先错信息3',
											},
validators=[
												RegexValidator(regex='root_\d+', message='错误了',code='c1'),
												RegexValidator(regex='root_112233\d+', message='又错误了',code='c2'),
												EmailValidator(message='又错误了', code='c3'), ]
)
			
python manage.py createsuperuser 创建超级用户
    
#admin.py
from home import models
admin.site.register(models.Test)

class Test(models.Model):
    name = models.CharField(max_length=32, null=True, db_column='username', db_index=True, verbose_name='姓名',help_text=("提示信息"))
    age = models.IntegerField(null=True, unique=True)
    email = models.EmailField(null=True)
    g = [
        (1, 'male'),
        (2, 'female')
    ]
    gender = models.IntegerField(choices=g, default=1)

    ip = models.GenericIPAddressField(null=True)
    file = models.FileField(null=True)
    from django.core.validators import RegexValidator
    from django.core.validators import EmailValidator, URLValidator, DecimalValidator, \
        MaxLengthValidator, MinLengthValidator, MaxValueValidator, MinValueValidator

    test = models.CharField(
        max_length=32,
        error_messages={
            'c1': '优先错信息1',
            'c2': '优先错信息2',
            'c3': '优先错信息3',
        },
        validators=[
            RegexValidator(regex='^root_\d+', message='错误了', code="c1"),
        ],
        null=True
    )

4.分页

内置分页
127.0.0.1/test1/?cur_page=1/

#views.py
def test1(request):
    # for i in range(300):
    #     name = "name" +str(i)
    #     models.UserInfo.objects.create(name=name,age=18)

    cur_page = request.GET.get('cur_page')
    userlist = models.UserInfo.objects.all()
    from django.core.paginator import Paginator

    # per page:每页显示条目数
    # count:数据总个数
    # num pages:总页数
    #page range: 总页数的索引范围,如(1,200)
    #page: page对象

    paginator =Paginator(userlist,15)

    # has next   是否下一页
    # next page number  下一页页码
    # has previous 是否上一页
    # between page number 上一页页码
    # object list 分页之后的数据类型
    # number 当前页
    # paginator paginator对象

    users = paginator.page(cur_page)
    return render(request,"index.html",{"users":users})

#index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% for user in users.object_list %}
        <li>{{ user.name }}</li>
    {% endfor %}

    {% if users.has_previous %}
        <a href="/test1/?cur_page={{ users.previous_page_number }}">上一页</a>
    {% endif %}

    {% for num in users.paginator.page_range %}
        <a href="/test1/?cur_page={{ num }}">{{ num }}</a>
    {% endfor %}

    {% if users.has_next %}
        <a href="/test1/?cur_page={{ users.next_page_number }}">下一页</a>
    {% endif %}

</body>
</html>
自定义分页

#views.py
class PageInfo():
    def __init__(self, cur_page, total, per_page=10, show_page=11):
        self.cur_page = cur_page
        self.per_page = per_page
        self.total = total
        self.show_page = show_page

        a, b = divmod(self.total, self.per_page)
        if b:
            a = a + 1
        self.total_page = a   #### 总页数

    #### 获取起始索引
    def get_start(self):
        start = (self.cur_page - 1) * self.per_page
        return start
    #### 获取结束索引
    def get_end(self):
        return self.cur_page * self.per_page

    def get_page(self):

        half  = (self.show_page - 1) // 2

        #### taotal_page = 5 < show_page = 11
        if self.total_page < self.show_page:
            begin = 1
            end = self.total_page
        else:
            #### 左边极值判断
            if self.cur_page - half <= 0 :
                begin = 1
                # end = self.cur_page + half
                end = self.show_page
            #### 右边极值的判断
            elif self.cur_page + half > self.total_page:
                # begin =  self.cur_page - half
                begin =  self.total_page - self.show_page + 1
                end = self.total_page   ### 31
            #### 正常页码判断
            else:
                begin = self.cur_page - half
                end = self.cur_page + half

        page_list = []
        if self.cur_page == 1:
            astr = "<li><a href='#' aria-label='Previous'><span aria-hidden='true'>&laquo;</span></a></li>"
        else:
            astr = "<li><a href='/custom/?cur_page=%s' aria-label='Previous'><span aria-hidden='true'>&laquo;</span></a></li>" % (self.cur_page-1)
        page_list.append(astr)

        for i in range(begin, end + 1):
            if self.cur_page == i:
                # astr = "<a style='display:inline-block; padding:5px;margin:5px;background-color:red;' href='/custom/?cur_page=%s'>%s</a>" % (i, i)
                astr = "<li class='active'><a href='/custom/?cur_page=%s'>%s</a></li>" % (i, i)
            else:
                # astr = "<a style='display:inline-block; padding:5px;margin:5px' href='/custom/?cur_page=%s'>%s</a>" % (i, i)
                astr = "<li><a href='/custom/?cur_page=%s'>%s</a></li>" % (i, i)
            page_list.append(astr)

        if self.cur_page == self.total_page:
            astr = "<li><a href='#' aria-label='Next'><span aria-hidden='true'>&raquo;</span></a></li>"
        else:
            astr = "<li><a href='/custom/?cur_page=%s' aria-label='Next'><span aria-hidden='true'>&raquo;</span></a></li>" % (self.cur_page+1)
        page_list.append(astr)

        s = " ".join(page_list)

        return s

def custom(request):

    cur_page = request.GET.get('cur_page')
    cur_page = int(cur_page)

    '''
    mysql:
       seelct * from userinfo limit 0, 10 
       seelct * from userinfo limit 10, 10 
       
       cur_page    start   show_page
          1          0     10
          2          10    10
          3          20    10
          n         (n-1)*10, 10
    limit (cur_page - 1) * show_page 
    '''
    # total = models.UserInfo.objects.count()
    total = models.UserInfo.objects.filter(id__lte=44).count()
    page = PageInfo(cur_page, total)
    start = page.get_start()
    end =  page.get_end()

    ### cur_page = 1   start = 0   end = 10
    ### cur_page = 2   start = 10  end = 20
    ### cur_page = 3   start  =20  end = 30
    # user_list = models.UserInfo.objects.all()[start:end]
    user_list = models.UserInfo.objects.filter(id__lte=44)[start:end]


    return render(request, "custom.html", {"user_list":user_list, "page":page})


#custom.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
    <ul>
        {% for user in user_list %}
            <li>{{ user.name }}</li>
        {% endfor %}
    </ul>


    <nav aria-label="Page navigation">
      <ul class="pagination">
          {{ page.get_page | safe}}
      </ul>
    </nav>
</body>
</html>
posted @ 2019-08-15 23:58  海森t  阅读(45)  评论(0)    收藏  举报