django之admin&model

admin.py文件

   # -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.contrib import admin
from . import models

# Register your models here.

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('nid','username','password','nickname','email','avatar','create_time')
    search_fields = ('username','nickname','email')
    list_filter = ('create_time',)
    # date_hierarchy = 'create_time'
    # 添加负号表示降序 这里的优先级高于model里的Meta 这个ordering选项基本像模块中class Meta的ordering那样工作,除了它只用列表中的第一个字段名。
    ordering = ('-nid',)

class UserFansAdmin(admin.ModelAdmin):
    list_display = ('user','follow')
    # 外键不显示为下拉框而显示为搜索框
    raw_id_fields = ('user','follow')

class ArticleAdmin(admin.ModelAdmin):
    # 多对多关系的tag不能再admin中显示
    list_display = ('tittle', 'summary','read_count','comment_count','up_count','down_count','create_time','blog','category')
    # 改变外键或一对一的添加方式
    raw_id_fields = ('blog','category')
    # 改变多对多的添加方式
    filter_horizontal = ('tags',)

# 手动创建第三张表可以在这里注册然后在admin里看到第三张表,但是自动创建的第三张表,这里没法注册导致admin里看不到
admin.site.register(models.UserInfo, UserInfoAdmin)
admin.site.register(models.UserFans, UserFansAdmin)
admin.site.register(models.Blog, BlogAdmin)
admin.site.register(models.Article, ArticleAdmin)
admin.site.register(models.ArticleDetail,ArticleDetailAdmin)
admin.site.register(models.UpDown,UpDownAdmin)
admin.site.register(models.Comment,CommentAdmin)
admin.site.register(models.Tag, TagAdmin)
admin.site.register(models.Category, CategoryAdmin)
admin.site.register(models.Tpl,TplAdmin)
admin.site.register(models.Trouble,TroubleAdmin)
# admin.site.register(models.Article2Tag)

model文件

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models

# Create your models here.

class UserInfo(models.Model):
    """
    用户表
    """
    nid = models.BigAutoField(primary_key=True)
    # verbose_name表示在admin中列表里显示的列名
    username = models.CharField(verbose_name='用户名', max_length=32, unique=True)
    password = models.CharField(verbose_name='密码', max_length=64)
    nickname = models.CharField(verbose_name='昵称', max_length=32)
    email = models.EmailField(verbose_name='邮箱', unique=True)
    avatar = models.ImageField(verbose_name='头像', upload_to='static/imgs/avatar', null=True, blank=True)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    # 用户和用户之间是多对多的互粉关系
    fans = models.ManyToManyField(
        verbose_name='粉丝们',
        to='UserInfo',#外键关联的是哪张表
        through='UserFans',#自定义第三张表的表名
        related_name='f',#反向查询时用的名称  默认_set
        through_fields=('user', 'follow')#自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
    )

    def __str__(self):
        return self.username

    class Meta:
        #根据nid降序 nid相同再根据username升序
        ordering = ['nid', 'username']
        verbose_name = "用户表"


class UserFans(models.Model):
    """
    手动创建的第三张关系表
    互粉关系表,手动创建的第三张关系表 ,自己和自己关联
    """
    user = models.ForeignKey(verbose_name='博主', to='UserInfo', to_field='nid', related_name='users', on_delete= models.CASCADE)
    follow = models.ForeignKey(verbose_name='粉丝', to='UserInfo', to_field='nid',related_name='followers', on_delete= models.CASCADE)

    class Meta:
        # 联合唯一索引
        unique_together = [
            ('user','follow')
        ]
        verbose_name = "粉丝表"


class Blog(models.Model):
    """
    博客信息
    """
    nid = models.BigAutoField(primary_key=True)
    tittle = models.CharField(verbose_name='博客标题', max_length=64)
    site = models.CharField(verbose_name='博客地址前缀', max_length=32, unique=True)
    theme = models.CharField(verbose_name='博客主题', max_length=32)
    # 一个博客属于一个人
    user = models.OneToOneField(verbose_name='所属人',to='UserInfo', to_field='nid', on_delete= models.CASCADE)

    def __str__(self):
        return self.tittle

    class Meta:
        verbose_name = "博客表"


class Category(models.Model):
    """
    个人文章分类
    """
    nid = models.AutoField(primary_key=True)
    tittle = models.CharField(verbose_name='分类标题', max_length=32)
    # 每个人的博客有多个不同类型的文章
    blog = models.ForeignKey(verbose_name="所属博客", to='Blog', to_field='nid', on_delete= models.CASCADE)

    def __str__(self):
        return self.tittle

    class Meta:
        verbose_name = "个人文章分类表"




class Article(models.Model):
    """
    文章表
    """
    nid = models.BigAutoField(primary_key=True)
    tittle = models.CharField(verbose_name='文章标题', max_length=128)
    summary = models.CharField(verbose_name='文章简介', max_length=255)
    read_count = models.IntegerField(verbose_name='阅读数', default=0)
    comment_count = models.IntegerField(verbose_name='评论数', default=0)
    up_count = models.IntegerField(verbose_name='点赞数', default=0)
    down_count = models.IntegerField(verbose_name='踩数', default=0)
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    # 一篇文章属于一个博客
    blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid', on_delete= models.CASCADE)
    # 一篇文章只属于一个类别
    # null如果为True , Django在数据库中会将空值(empty)存储为NULL 。默认为False
    # blank设置字段是否可以为空,默认为False(不允许为空)。
    # null是数据库的范围,而blank是用于验证。如果一个字段的blank = True ,Django在进行表单数据验证时,会允许该字段是空值。如果字段的
    # blank = False ,该字段就是必填的。
    category = models.ForeignKey(verbose_name='文章类型', to='Category', to_field='nid', null=True, blank=True, on_delete= models.CASCADE)

    type_choices = [
        (1,'python'),
        (2,'linux'),
        (3,'java'),
        (4,'php')
    ]
    # 如果设置了choices, Django会显示选择框,而不是标准的文本框,而且这个选择框的选项就是choices中的元组。
    # 每个元组中的第一个元素,是存储在数据库中的值;第二个元素是在管理界面或ModelChoiceField中用作显示的内容。在一个给定的
    # model类的实例中,想得到某个choices字段的显示值,就调用a.get_type_choices_display(); a是文章对象

    article_type_id = models.IntegerField(choices=type_choices, default=None,null=True,blank=True)

    # 这里使用自动创建第三张表
    tags = models.ManyToManyField(
        to='Tag',
        # through='Article22Tag',
        # through_fields=('article','tag'),
    )

    def __str__(self):
        return self.tittle

    class Meta:
        verbose_name = "文章表"



class ArticleDetail(models.Model):
    """
    文章详情
    """
    content = models.TextField(verbose_name='文章内容')
    # 一篇文章详情属于一篇文章
    # 手动创建第三张表可以在这里注册然后在admin里看到第三张表,但是自动创建的第三张表,admin里没法注册导致admin里看不到
    article = models.OneToOneField(verbose_name='所属文章', to='Article', to_field='nid', on_delete= models.CASCADE)

    def __str__(self):
        return self.content

    class Meta:
        verbose_name = "文章详情表"


class UpDown(models.Model):
     """
     文章踩或顶
     """
     article = models.ForeignKey(verbose_name='文章', to='Article', to_field='nid', on_delete= models.CASCADE)
     user = models.ForeignKey(verbose_name='踩或顶的用户', to='UserInfo', to_field='nid', on_delete= models.CASCADE)
     up = models.BooleanField(verbose_name='是否赞')

     def __str__(self):
         return self.article

     class Meta:
         # 联合唯一索引
         unique_together=[
             ('article','user'),
         ]

         verbose_name = "文章顶踩表"



class Comment(models.Model):
    """
    评论表
    """
    nid = models.BigAutoField(primary_key=True)
    content = models.CharField(verbose_name='评论内容', max_length=255)
    create_time = models.DateTimeField(verbose_name='评论时间', auto_now_add=True)

    # 一个评论对应一篇文章,一篇文章有多个评论
    article = models.ForeignKey(verbose_name="评论文章", to='Article', to_field='nid', on_delete= models.CASCADE)
    # 一个评论属于一个人,一个人可以给出多个评论
    user = models.ForeignKey(verbose_name='评论者', to='UserInfo', to_field='nid', on_delete= models.CASCADE)
    reply = models.ForeignKey(verbose_name='回复评论', to='Comment', related_name='back', null=True, blank=True, on_delete= models.CASCADE)

    class Meta:
        verbose_name = "评论表"

    def __str__(self):
        return self.content

class Tag(models.Model):
    nid = models.AutoField(primary_key=True)
    tittle = models.CharField(verbose_name='标签名称', max_length=32)
    # 每个人的标签是独立的  一个人有多个标签
    blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid',on_delete= models.CASCADE)

    def __str__(self):
        return self.tittle

    class Meta:
        verbose_name = "标签表"


# class Article2Tag(models.Model):
#     article = models.ForeignKey(verbose_name='文章', to='Article', to_field='nid', on_delete= models.CASCADE)
#     tag = models.ForeignKey(verbose_name='标题', to='Tag', to_field='nid', on_delete= models.CASCADE)
#
#     class Meta:
#         # 联合唯一索引
#         unique_together=[
#             ('article', 'tag')
#         ]


# class Article22Tag(models.Model):
#     article = models.ForeignKey(verbose_name='文章', to='Article', to_field='nid', on_delete= models.CASCADE)
#     tag = models.ForeignKey(verbose_name='标题', to='Tag', to_field='nid', on_delete= models.CASCADE)
#
#     class Meta:
#         # 联合唯一索引
#         unique_together=[
#             ('article', 'tag')
#         ]
class Tpl(models.Model):
    tittle = models.CharField(max_length=32,verbose_name='标题')
    content = models.TextField(verbose_name='内容')

    def __str__(self):
        return self.tittle

    class Meta:
        verbose_name = "问题表"


class Trouble(models.Model):
    tittle = models.CharField(max_length=32,verbose_name='标题')
    detail = models.TextField(verbose_name='详细情况')
    user = models.ForeignKey(UserInfo,related_name='u', on_delete=models.CASCADE,verbose_name='来自用户')
    ctime = models.DateTimeField(verbose_name='创建时间')
    status_choices = (
        (1,'未处理'),
        (2,'处理中'),
        (3,'已处理')
    )
    status = models.IntegerField(choices=status_choices,default=1,verbose_name='处理状态')

    processer = models.ForeignKey(UserInfo,related_name='p',null=True,blank=True,on_delete=models.CASCADE,verbose_name='处理人')
    solution = models.TextField(null=True,verbose_name='解决情况')
    ptime = models.DateTimeField(null=True,verbose_name='解决时间')

    pj_choice = (
        (1,'不满意'),
        (2,'一般'),
        (3,'很好'),
    )
    pj = models.IntegerField(choices=pj_choice, null=True, default=2,verbose_name='评价')

    def __str__(self):
        return self.tittle

    class Meta:
        verbose_name = "问题详情表"

用safe过滤器为单独的变量关闭自动转意:

This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
#结果
This will be escaped: <b>
This will not be escaped: <b>

为了控制模板的自动转意,用标签autoescape来包装整个模板(或者模板中常用的部分)

{% autoescape off %}
    This will not be auto-escaped: {{ data }}.

    Nor this: {{ other_data }}
    {% autoescape on %}
        Auto-escaping applies again: {{ name }}
    {% endautoescape %}
{% endautoescape %}

auto-escaping 标签的作用域不仅可以影响到当前模板还可以通过include标签作用到其他标签,就像block标签一样。

# base.html
{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}

# child.html

{% extends "base.html" %}
{% block title %}This & that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}

Managers(针对整个表的方法,选出来的是某些满足条件的对象)

为Book模型定义了一个title_count()方法,它需要一个关键字,返回包含这个关键字的书的数量。

我们把BookManager()赋值给模型的objects属性。 它将取代模型的默认manager(objects)如果我们没有特别定义,它将会被自动创建。 我们把它命名为objects,这是为了与自动创建的manager保持一致。
# models.py

from django.db import models

# ... Author and Publisher models here ...

**class BookManager(models.Manager):**
    **def title_count(self, keyword):**
        **return self.filter(title__icontains=keyword).count()**

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()
    num_pages = models.IntegerField(blank=True, null=True)
    **objects = BookManager()**

    def __unicode__(self):
        return self.title

重写父类的方法(找某个作者的所有书)

注意我们明确地将objects设置成manager的实例,因为如果我们不这么做,那么唯一可用的manager就将是dah1_objects。

from django.db import models

**# First, define the Manager subclass.**
**class DahlBookManager(models.Manager):**
    **def get_query_set(self):**
        **return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')**

**# Then hook it into the Book model explicitly.**
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)
    # ...

    **objects = models.Manager() # The default manager.**
    **dahl_objects = DahlBookManager() # The Dahl-specific manager.**

同一模型中使用多个Manager

这个例子允许你执行Person.men.all() ,Person.women.all() ,Person.people.all() 查询,生成你想要的结果。

class MaleManager(models.Manager):
    def get_query_set(self):
        return super(MaleManager, self).get_query_set().filter(sex='M')

class FemaleManager(models.Manager):
    def get_query_set(self):
        return super(FemaleManager, self).get_query_set().filter(sex='F')

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
    people = models.Manager()
    men = MaleManager()
    women = FemaleManager()

模型方法(针对的是某个对象,查询的是对象的信息)

from django.contrib.localflavor.us.models import USStateField
from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    birth_date = models.DateField()
    address = models.CharField(max_length=100)
    city = models.CharField(max_length=50)
    state = USStateField() # Yes, this is U.S.-centric...

    def baby_boomer_status(self):
        "Returns the person's baby-boomer status."
        import datetime
        if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
            return "Baby boomer"
        if self.birth_date < datetime.date(1945, 8, 1):
            return "Pre-boomer"
        return "Post-boomer"

    def is_midwestern(self):
        "Returns True if this person is from the Midwest."
        return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')

    def _get_full_name(self):
        "Returns the person's full name."
        return u'%s %s' % (self.first_name, self.last_name)
    #将方法赋给他的一个属性,调用时直接p.full_name而不是p.full_name()
    full_name = property(_get_full_name)

使用方式

>>> p = Person.objects.get(first_name='Barack', last_name='Obama')
>>> p.birth_date
datetime.date(1961, 8, 4)
>>> p.baby_boomer_status()
'Baby boomer'
>>> p.is_midwestern()
True
>>> p.full_name  # Note this isn't a method -- it's treated as an attribute
u'Barack Obama'

执行原生SQL

不要把你的视图代码和django.db.connection语句混杂在一起,把它们放在自定义模型或者自定义manager方法中是个不错的主意。

cursor.fetchone():将只取最上面的第一条结果,返回单个元组如(‘id‘,‘title‘),然后多次使用cursor.fetchone(),依次取得下一条结果,直到为空。

cursor.fetchall() :将返回所有结果,返回二维元组,如((‘id‘,‘title‘),(‘id‘,‘title‘)),

如果select本身取的时候只有一条数据时:

cursor.fetchone():将只返回一条结果,返回单个元组如(‘id‘,‘title‘)。

cursor.fetchall() :也将返回所有结果,返回二维元组,如((‘id‘,‘title‘),),

from django.db import connection, models

class PersonManager(models.Manager):
    def first_names(self, last_name):
        cursor = connection.cursor()
        cursor.execute("""
            SELECT DISTINCT first_name
            FROM people_person
            WHERE last_name = %s""", [last_name])
        return [row[0] for row in cursor.fetchone()]

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    objects = PersonManager()
posted @ 2018-05-11 16:39  py小杰  阅读(175)  评论(0)    收藏  举报