美文网首页
Django 后台

Django 后台

作者: 高阳刘 | 来源:发表于2017-10-26 13:58 被阅读0次

django的后台我们只要少写些代码,就可以实现强大的功能,与后台相关文件:每个app中的admin.py文件与后台相关

下面实例是做一个后台添加博客文章的例子:
####### 1、新建一个名称为learn_admin的项目

django-admin.py startproject learn_admin
2、新建一个叫做blog的app
# 进入 learn_admin这个文件夹
cd learn_admin/
# 创建blog这个app
python manage.py startapp blog
# 注意不同版本的Django创建project和app出来的文件会有一些不同
3、修改blog文件中的models.py
from django.db import models
# Create your models here.

class Article(models.Model):
    title = models.CharField(max_length=256, '标题')
    content = models.TextField('内容')
    pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
    updatetime= models.DateTimeField('更新时间', auto_now=True, null=True)
    
# 前三个modelField,DateTimeField和DateField和TimeField存储的内容分别对应着datetime(),date(),time()三个对象。
# 对于auto_now=False和auto_now_add=False两者默认值都为False。
 # auto_now=Ture,字段保存时会自动保存当前时间,但要注意每次对其实例执行save()的时候都会将当前时间保存,也就是不能再手动给它存非当前时间的值。
# auto_now_add=True,字段在实例第一次保存的时候会保存当前时间,不管你在这里是否对其赋值。但是之后的save()是可以手动赋值的。也就是新实例化一个model,想手动存其他时间,就需要对该实例save()之后赋值然后再save()。
4、把blog加入到settings.py中的 INSTALLED_APPS中
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
]
# 提示:INSTALLED_APPS是一个列表,每次加入新的app的时候,在后面都加一个逗号,这是一个好习惯
5、同步所有的数据表
# 进入包含有 manage.py的文件夹
python manage.py makemigrations
python manage.py migrate

# 注意:Django 1.6.x及以下的版本需要以下命令
python manage.py syncdb

# 如果是Django 不主动提示创建管理员(Django 1.9不提示),用下面的命令创建一个账号

python manage.py createsuperuser
# 创建用户名,不写默认taytay
Username (leave blank to use 'taytay'): learn_user
Email address: 123@163.com
Password: 
Password (again): 
Superuser created successfully.
修改 admin.py

进入blog文件夹,修改admin.py(如果没有新建一个),内容如下:

from django.contrib import admin

# Register your models here.
from .models import Article

admin.site.register(Article)

# 只需要这三行代码,我们就可以拥有一个强大的后台

提示:urls.py中关于admin的已经默认开启,如果没有,参考这里

7、打开开发服务器
python manage.py runserver
# 如果提示 8000端口已经被占用,可以用python manage.py runserver 8001 以此类推
Performing system checks...

System check identified no issues (0 silenced).
October 26, 2017 - 03:28:38
Django version 1.11, using settings 'learn_admin.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C

访问 http://127.0.0.1:8000/admin/login/?next=/admin/ 然后输入设定的账号和密码,就可以看到

点击Articles,动手输入添加几篇文章,就可以看到:


我们会发现所有的文章都是叫 Article object,这样肯定不好,比如我们要修改,如何知道修改那个呢?

我们修改一下blod中的model.py

class Article(models.Model):
    title = models.CharField('标题', max_length=256)
    content = models.TextField('内容')
    pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
    updatetime= models.DateTimeField('更新时间', auto_now=True, null=True)

    def __str__(self):
        return self.title
# 在python2中用__unicode__:代替__str__

我们加入一个str函数,刷新网页,会看到:

所以推荐定义Model的时候写一个str函数(或unicode函数)

提升技能,如何兼容python2.x和python3.x呢?

示例如下:

from __future__ import unicode_literals

from django.db import models

from django.utils.encoding import python_2_unicode_compatible
# Create your models here.


@python_2_unicode_compatible 
class Article(models.Model):
    title = models.CharField('标题', max_length=256)
    content = models.TextField('内容')
    pub_date = models.DateTimeField('发表时间', auto_now_add=True, editable=True)
    updatetime= models.DateTimeField('更新时间', auto_now=True, null=True)

    def __str__(self):
        return self.title

python_2_unicode_compatible会自动做一些处理去适应python不同的版本,本例中的unicode_literals可以让python2.x也像python3那样处理Unicode字符,以便更好的兼容

8、在列表显示字段相关其他内容

后台基本已经做出来了,可是如果我们还需要显示一些其他的fields,如何做呢?

from django.contrib import admin

# Register your models here.
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'pub_date', 'update_time',)

admin.site.register(Article, ArticleAdmin)

list_display就是来配置要现实的字段,当然也可以显示非字段内容,或者字段相关的内容,比如:

class People(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    
    def my_property(self):
        return self.first_name + ' ' + self.last_name
    my_property.short_description = 'Full name of the person'
    
    full_name = property(my_property)

在admin.py中:

from django.contrib import admin

# Register your models here.
from .models import *

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'pub_date', 'update_time',)

admin.site.register(Article, ArticleAdmin)

class PeopleAdmin(admin.ModelAdmin):
    list_display = ('full_name')

admin.site.register(People , PeopleAdmin)

到这里我们发现又有新的需求,比如要改models.py中的字段,添加一个文章的状态(草稿,正式发布),这时候我们就需要更改表,django1.7以前的都不会自动更改表,我们需要第三方插件South
Django 1.7及以上 用一下命令同步数据库表的更改

python manage.py makemigrations
python manage.py migrate
有时候我们需要对Django admin site 进行修改以满足自己的需求,那么我们可以从哪些地方入手呢?

以下举例说明:
1、定制加载的列表,根据不同的人显示不同的内容列表,比如输入员只能看见自己输入的,审核员能看到所有的草稿,这时候就需要重写get_queryset方法

class MyModelAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super(MyModelAdmin, self).get_queryset(request)
        
        if request.user.is_superuser:
            return  qs
        else:
            return qs.filter(author=request.user)
# 该类实现的功能是如果是超级管理员就累出所有,如果不是,就近列出访问者自己相关的

2、定制搜索功能(django 1.6以上才有)

class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age')
    search_fields = ('name',)

    def get_search_results(self, request, queryset, search_term):
        queryset, use_distinct = super(PersonAdmin, self).get_search_results(request, queryset, search_term)
        try:
            search_term_as_int = int(search_term)
            queryset |= self.model.objects.filter(age=search_term_as_int)
        except:
            pass
        return queryset, use_distinct
# queryset是默认的结果,search_term是在后台搜索的关键词

3.修改保存时的一些操作,可以检查用户,保存的内容等,比如保存时加上添加人

from django.contrib import admin
 
class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.user = request.user
        obj.save()

其中obj是修改后的对象,form是返回的表单(修改后的),当新建一个对象时 change = False, 当修改一个对象时 change = True
如果需要获取修改前的对象的内容可以用

from django.contrib import admin
 
class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj_original = self.model.objects.get(pk=obj.pk)
        obj.user = request.user
        obj.save()

那么又有问题了,这里如果原来的obj不存在,也就是如果我们是新建的一个怎么办呢,这时候可以用try,except的方法尝试获取,当然更好的方法是判断一下这个对象是新建还是修改,是新建就没有 obj_original,是修改就有

from django.contrib import admin
 
class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        if change:# 更改的时候
            obj_original = self.model.objects.get(pk=obj.pk)
        else:# 新增的时候
            obj_original = None
 
        obj.user = request.user
        obj.save()

4, 删除时做一些处理,

from django.contrib import admin
 
class ArticleAdmin(admin.ModelAdmin):
    def delete_model(self, request, obj):
        """
        Given a model instance delete it from the database.
        """
        # handle something here
        obj.delete()

相关文章

网友评论

      本文标题:Django 后台

      本文链接:https://www.haomeiwen.com/subject/wzphpxtx.html