需求是根据当前登录用户来显示某个choice字段不同的选择项。

先放现在的实现版本。

1、重写PushRuleForm的__init__方法,

让每次实例化PushRuleForm时,test_mode字段的choices根据用户重新赋值

class PushRuleForm(forms.ModelForm):  
  def __init__(self, *args, **kwargs):
    if self.request.user.username in Const.TEST_USER_LIST:
      # 如果进入都是add添加新项的页面
      if not kwargs.get('instance'):
        # self.fields['test_mode'].initial = 1
        self.fields['test_mode'].choices = [(1,'Test')]
      # else:
      #   self.fields['test_mode'].choices = [choice for choice in [(0,'OnLine'),(1,'Test')] if self.instance.test_mode in choice]

2、重写PushRuleAdmin的changeform_view方法,进入add和change页面都会调用changeform_view方法,都能让form获取request属性,所以重写这个方法比较好,PushRuleForm获取request属性后,form表单处理是就能通request.user.username取用户名

class PushRuleAdmin:
  form = PushRuleForm
  def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
    self.form.request = request
    return super(PushRuleAdmin, self).changeform_view(request, object_id, extra_context=extra_context)

mode.py对应的代码如下:

class PushRule(models.Model):  
  test_mode  = models.IntegerField(verbose_name='TestMode', default=0, choices=[(0,'OnLine'),(1,'Test')])

实现方式2:

,重写PushRuleAdmin的render_change_form方法,传入test_user_list上下文,通过js来判断当前用户是否是测试用户。

class PushRuleAdmin:
  def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
    context['test_user_list']=Const.TEST_USER_LIST
    return super(PushRuleAdmin, self).render_change_form(request, context, add=False, change=False, form_url='', obj=None)

js代码:

  if (test_user_list.includes(username))
  {
    $("#id_test_mode > option[value='0']").remove();
  }

html模板代码:

为了让js获取django模板变量,先定义一个username和test_user_list变量

<script> var username="{{ user.username }}", test_user_list="{{ test_user_list }}"</script>

不过这么的坏处是用户列表信息直接暴露在前端代码里了,跟直接在js里维护一个测试用户列表一样的效果,遂放弃这种做法

实现方式3:

后端写一个视图接口,返回对应的test_user_list,js里写一个ajax请求,来请求这个视图获取test_user_list

实测没有问题。

实现方式4:

类似方法2,只不过不通过js来处理,直接通过django模板来处理,主要是重写django/contrib/admin/templates/admin/includes/fieldset.html这个模板文件,对django模板语法不太熟,遂放弃。

未实现的思路,想在PushRuleAdmin中直接修改model的test_mode字段的chioce选项,不过没实现,

想修改model的fields,不过发现他是一个ImmutableList类型,修改会报错。

不过stackoverflow上的给出的这个方法不错,可以参考,就是缺一个获取用户名的地方,哪天再看一下

补充知识:django 中优雅的使用 choice 字段

问题

django中如何比较优雅的对元组进行标记分类。可使用choice字段

choice字段

# models.py
class BookTagNum(object):
  OTHER = 1
  SCIENCE = 2
  SOCIAL_SCIENCES = 3
  ECONOMIC = 4
  COMPUTER = 5

class BOOK(models.Model):
  TAG_NUM_CHOICE = (
    (BookTagNum.OTHER, '其它'),
    (BookTagNum.SCIENCE, '科学类'),
    (BookTagNum.SOCIAL_SCIENCES, '社科类'),
    (BookTagNum.ECONOMIC, '经济类'),
    (BookTagNum.COMPUTER, '计算机类'),
  )
  tag = models.IntegerField(choices=TAG_NUM_CHOICE)

在代码中尽量不要出现固定的硬编码,比如某个判断条件,判断书的分类为:

# view.py
def get(self, request):
 book = Book.obejects.filter(tag = BookTagNum.COMPUTER)

以上这篇django实现模型字段动态choice的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。