【问题标题】:make some model field conditionally visible in django使一些模型字段在 django 中有条件地可见
【发布时间】:2018-09-26 23:51:41
【问题描述】:

我的 django 模型中有两个字段,只有当用户选择“类型”作为“维度”时它们才应该是可编辑的,否则它们不应该对用户可见。

我的模型是这样的代码

from django.db import models

class Configuration(models.Model):

   name = models.CharField(max_length=30)
   user_defined_name = models.CharField(max_length=50)
   FieldTypes = (('aD', 'Dimension'), ('aM', 'Measure'))
   type = models.CharField(max_length=11, choices=FieldTypes)
   is_key = models.BooleanField(default=False, editable=False)
   unit = models.CharField(max_length=30, null=True, blank=True, editable=False)


   def __str__(self):
       return self.name

我知道使用 JavaScript 是可能的,但是我不想自己写 html 或 js,因此不能使用 JavaScript 来做到这一点。

【问题讨论】:

  • 您不必编写 HTML。将所有 JS 代码写入 .js 文件并使用 class Media 将该文件提供给 ModelAdmin。
  • 有没有办法只使用 Django 功能......而不用自己使用 js
  • 如果用户选择需要从视图中处理的类型,您需要为其创建单独的模型并创建多部分表单(向导视图)。如果你试图在没有 js 的情况下处理这个问题会很危险
  • 类型选择发生在 Django 的上下文之外;它发生在浏览器上。因此,JS 是放置此代码的合适位置。它也很容易做到,我建议您检查一下。
  • @xyres 终于用 JS 完成了。然后我覆盖保存方法以删除额外的字段数据,但是该 JS 文件正在加载到我的所有管理部分中,其中不存在编辑表单,因此出现错误。你能帮我吗

标签: python-3.x django django-models


【解决方案1】:

如果 type 不等于 Dimension,则纯 Django 唯一的方法是简单地重置 ModelForm 中的字段。这看起来像是魔术/意外行为;所以要小心执行。

例如(假设您使用的是管理界面:同样适用于自定义 ModelForm 视图):

class ConfigurationAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        #  At this point; the object already has the new values set; we will have to reset as needed
        conditional_editable_fields = ['is_key', 'unit']
        config_type = form.cleaned_data.get('type')
        if config_type != 'aD':
            for field in conditional_editable_fields:
                if field in form.changed_data:  # The value has been changed by the user
                    setattr(obj, field, form.initial.get(field))  # Set the initial value
                    self.message_user(request, "Cannot edit field: {}; value has been reset".format(field), messages.WARNING)  # Inform the user that we reset the value
        return super(ConfigurationAdmin, self).save_mode(request, obj, form, change)

【讨论】:

    【解决方案2】:

    我为此使用了类似的方法。
    我很好用 在我的 admin.py 中

    `
        fieldsets = (
            (None, {
                'fields': ('name', 'user_defined_name', 'type', 'is_active')
            }),
            ('Advanced', {
                'classes': ('toggle',),
                'fields': ('is_kpi', 'unit'),
            })
        )
        actions = [disable_multiple_column, activate_multiple_column]
    
        class Media:
            js = ("jquery.js", "my_code.js",)`
    

    我使用那个 JS 文件来显示和隐藏。

        `$(document).ready(function(){
            show_hide();
            $('#id_type').change(function(){
                show_hide();
            });
            function show_hide(){
                if ($("#id_type").val() == 'aM' ){
                        $(".module")[1].style.display="block"
                    }
                else{
                     $(".module")[1].style.display="none"
                }
            }
        });`
    

    如果使用已经输入的值,然后更改类型选择或其他原因,这些隐藏字段仍然有数据。我覆盖了models.py的save方法

    `
        def save(self, *args, **kwargs):
            if self.type != 'aM':
                self.is_kpi = False
                self.unit = None
            super(Configuration, self).save(*args, **kwargs)
    `
    

    【讨论】:

      猜你喜欢
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      • 2019-08-27
      • 1970-01-01
      • 1970-01-01
      • 2012-05-14
      • 2015-04-02
      相关资源
      最近更新 更多