Django Admin 实现外键过滤的方法


Posted in Python onSeptember 29, 2017

说明和 Model

环境:

➜ python

Python 3.6.3 |Anaconda custom (x86_64)| (default, Oct 6 2017, 12:04:38)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print(django.get_version())
2.0.1
>>>

2018年05月23日更新:

可以通过get_changeform_initial_data 函数来传递initial参数.

# admin.py
@admin.register(Score)
class ScoreConfigAdmin(FilterUserAdmin):
  # fields = ('id','name')
  form = ScoreConfigAdminForm

  def get_changeform_initial_data(self, request):
    initial = super().get_changeform_initial_data(request)
    initial.update({'uid': request.user.id})
    return initial

# forms.py
class ScoreConfigAdminForm(forms.ModelForm):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    if not kwargs.get('initial'):
      return
    self.uid = kwargs.get('initial').get('uid')

  class Meta:
    model = Score
    fields = '__all__'

有一个支持多用户(使用 django admin)的 Blog,每一篇 Post 都需要记录是谁发表的并且属于那个 Blog。

user 与 Blog 的关系、 Blog 与 Post 有2种定义方式,一种是使用独立关系表,另外一种是直接在 Model 中定义中使用外键。

后面一种的 model 定义如下:

from django.contrib.auth.models import User
from django.db import models

class Blog(models.Model):
  '''
  Blog
  '''
  id = models.AutoField(unique=True, primary_key = True, verbose_name="序号")
  name = models.CharField(max_length=255, blank=True, null=True, verbose_name="名称")
  user = models.ForeignKey(User, on_delete=models.CASCADE)
  create_time = models.DateTimeField(verbose_name='添加时间', auto_now_add=True, blank=True)

  class Meta:
    verbose_name = 'Blog'
    verbose_name_plural = 'Blog管理'

  def __str__(self):
    return self.name

class Post(models.Model):
  '''
  Post 内容
  '''
  id = models.AutoField(unique=True, primary_key = True, verbose_name="序号")
  title = models.CharField(max_length=255, blank=True, null=True, verbose_name="标题")
  content = models.TextField(max_length=1024, blank=True, null=True, verbose_name="内容")
  blog = models.ForeignKey(Blog, on_delete=models.CASCADE, verbose_name="所属Blog")
  user = models.ForeignKey(User, on_delete=models.CASCADE)
  create_time = models.DateTimeField(verbose_name='添加时间', auto_now_add=True, blank=True)

  class Meta:
    verbose_name = '文章'
    verbose_name_plural = '文章管理'

  def __str__(self):
    return self.title

Admin 中实现

admin 中有2处,一处是 Blog 和 Post 列表中按 user 过滤,另外一处是新增 Post 时需要按当前 user 过滤。完整代码如下:

from django.contrib import admin
from django import forms

# Register your models here.
from django_summernote.admin import SummernoteModelAdmin
from .models import Team, Member, Activity, Score



from .models import Blog, Post
class FilterUserAdmin(admin.ModelAdmin):
  '''
  按所属用户过滤的 base, class
  '''
  def save_model(self, request, obj, form, change):
    # TODO 需要考虑不同用户对同一数据进行修改。
    obj.user = request.user
    obj.save()

  def get_queryset(self, request):
    # For Django < 1.6, override queryset instead of get_queryset
    qs = super(FilterUserAdmin, self).get_queryset(request) 
    # 不能加这个,加了这个会导致 superuser 更新普通用户的数据。
    # if request.user.is_superuser:
    #   return qs
    return qs.filter(user=request.user)

  def has_change_permission(self, request, obj=None):
    has_class_permission = super(FilterUserAdmin, self).has_change_permission(request, obj)
    if not has_class_permission:
      return False
    if obj is not None and not request.user.is_superuser and request.user.id != obj.user.id:
      return False
    return True


class BlogConfigAdmin(FilterUserAdmin):
  list_display = ('id','name', 'create_time')
  exclude = ['user']
  list_per_page = 50

admin.site.register(Blog, BlogConfigAdmin)


class PostConfigAdmin(FilterUserAdmin):
  list_display = ('id','title', 'create_time')
  exclude = ['user']
  list_per_page = 50

  def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    # 新增 Post 时,相关联的 Blog 需要过滤,关键就在下面这句。
    context['adminform'].form.fields['blog'].queryset = Team.objects.filter(user=request.user)
    return super(MemberConfigAdmin, self).render_change_form(request, context, add, change, form_url, obj)


admin.site.register(Post, PostConfigAdmin)

说2句

在render_change_form中下断点,直接调试下会发现更多有趣的内容。

以上这篇Django Admin 实现外键过滤的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python发送HTTP请求的方法小结
Jul 08 Python
用ReactJS和Python的Flask框架编写留言板的代码示例
Dec 19 Python
Linux下python与C++使用dlib实现人脸检测
Jun 29 Python
python中多个装饰器的执行顺序详解
Oct 08 Python
Python变量访问权限控制详解
Jun 29 Python
给大家整理了19个pythonic的编程习惯(小结)
Sep 25 Python
keras实现调用自己训练的模型,并去掉全连接层
Jun 09 Python
浅谈优化Django ORM中的性能问题
Jul 09 Python
Python如何实现机器人聊天
Sep 10 Python
Selenium环境变量配置(火狐浏览器)及验证实现
Dec 07 Python
python RSA加密的示例
Dec 09 Python
Python之Matplotlib绘制热力图和面积图
Apr 13 Python
python 调用c语言函数的方法
Sep 29 #Python
python文件名和文件路径操作实例
Sep 29 #Python
Python 实现简单的shell sed替换功能(实例讲解)
Sep 29 #Python
Python 基础教程之闭包的使用方法
Sep 29 #Python
python下实现二叉堆以及堆排序的示例
Sep 29 #Python
Python数据结构与算法之链表定义与用法实例详解【单链表、循环链表】
Sep 28 #Python
Python实现压缩和解压缩ZIP文件的方法分析
Sep 28 #Python
You might like
玩家交还《星际争霸》原始码光盘 暴雪报以厚礼
2017/05/05 星际争霸
一个改进的UBB类
2006/10/09 PHP
在PHP中操作Excel实例代码
2010/04/29 PHP
php中实现记住密码下次自动登录的例子
2014/11/06 PHP
php导入excel文件到mysql数据库的方法
2015/01/14 PHP
php使用APC实现实时上传进度条功能
2015/10/26 PHP
PHP快速排序算法实现的原理及代码详解
2019/04/03 PHP
JavaScript 中的replace方法说明
2007/04/13 Javascript
JavaScript 克隆数组最简单的方法
2009/02/12 Javascript
jquery 学习之一 对象访问
2010/11/23 Javascript
php跨域调用json的例子
2013/11/13 Javascript
JavaScript实现的石头剪刀布游戏源码分享
2014/08/22 Javascript
详解JavaScript逻辑And运算符
2015/12/04 Javascript
js之切换全屏和退出全屏实现代码实例
2019/09/09 Javascript
关于JS模块化的知识点分享
2019/10/16 Javascript
TypeScript的安装、使用、自动编译的实现
2020/04/10 Javascript
python网络编程之读取网站根目录实例
2014/09/30 Python
Php多进程实现代码
2018/05/07 Python
python3使用SMTP发送简单文本邮件
2018/06/19 Python
pycharm重置设置,恢复默认设置的方法
2018/10/22 Python
Django学习之文件上传与下载
2019/10/06 Python
PyTorch中model.zero_grad()和optimizer.zero_grad()用法
2020/06/24 Python
你在项目中用到了xml技术的哪些方面?如何实现的?
2014/01/26 面试题
个人简历的自荐信
2013/10/23 职场文书
幼儿教师自我鉴定
2013/11/02 职场文书
冰淇淋开店创业计划书
2014/02/01 职场文书
财务总监管理岗位职责
2014/03/08 职场文书
人力资源管理系自荐信
2014/05/31 职场文书
消防宣传口号
2014/06/16 职场文书
小学生放飞梦想演讲稿
2014/08/26 职场文书
奥巴马当选演讲稿
2014/09/10 职场文书
专题组织生活会思想汇报
2014/10/01 职场文书
三严三实心得体会范文
2014/10/13 职场文书
电影复兴之路观后感
2015/06/02 职场文书
演讲稿:​快乐,从不抱怨开始!
2019/04/02 职场文书
Sql-Server数据库单表查询 4.3实验课
2021/04/05 SQL Server