有没有办法从 Django admin 中转换 on/off 特定字段?

Is there a way to turn on/off a particular field from Django admin?

我想在我的 Django 管理仪表板中实现一个设置,我可以在其中 disable/enable 一个特定的字段。如果我应该禁用该字段,该字段中的数据将不会呈现在网页上。如果我应该启用该字段,那么数据将显示在网页中。我只想从我的管理仪表板执行此操作。

这是我的 models.py:

class Product(models.Model):
    category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(max_length=100, unique=True)
    image = models.ImageField(upload_to='products/')
    description = models.TextField()
    quantity = models.CharField(max_length=10)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    available = models.BooleanField(default=True)

这是admin.py:

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ('name', 'category', 'slug', 'price', 'available')
    list_filter = ('category', 'available')
    list_editable = ('price', 'available')
    prepopulated_fields = {'slug': ('name',)}

我希望能够从我的管理仪表板 enable/disable(可能像一个切换按钮)description 字段。有没有办法在我的 admin.py 文件中实现它?我该怎么做?谢谢。

编辑:为了更好地理解(如评论所建议的),我想在管理仪表板中实现一个主切换,该切换 on/off 每个实例的所有描述显示给用户。

Django constance (no association to myself) might do what you want. It doesn't necessarily store the toggle you're describing in any way connected to your model, but it will allow you to have editable settings. This can be used in your form definition or passed to your context through either the view or a context processor.

有几种方法。

1 权限管理员用户。 2 bool 显示或不显示对象。 3 新的管理视图。

1

您可以添加查看此字段的权限,并在 admin.py 或 return None 中创建一个方法来查看它,具体取决于权限值。

在admin.py在

class YourAdminClass(admin.ModelAdmin)
    def get_queryset(self, request):
         queryset= super(YourAdminClass, self).get_queryset(request)
         self.request = request
         return queryset 

    def mobile_phone(self, obj):
        return obj.user.mobile_phone if self.request.user.has_special_permission else None

2

您可以向对象添加一个布尔值而不是用户权限(在管理员中显示或不显示)并更改选项 1 中的查询集(这样您可以从客户端 FE 控制它)

def get_queryset(self, request):
    qs = super(YourAdminClass, self).get_queryset(request)
    return qs.filter(SHOW_MY_FIELD=True)

3

创建新的管理视图 NoFieldAdmin 和替代管理,并通过管理 url 在主管理中显示或不显示 link 在主 admin.py 文件中

class NoFieldAdminSite(AdminSite):
    pass
    #or overwrite some methods for different functionality

NoFieldAdmin= NoFieldAdminSite(name="nofield_admin")   

in urls.py
        urlpatterns = [
            url(r'^admin/', admin.site.urls),
            url(r'^NOFIELD-admin/', NoFieldAdmin.urls),

您可以执行以下操作:

首先,将此字段添加到您的 models.py:

is_description = models.BooleanField(default=True)

然后进行迁移:

python manage.py makemigrations
python manage.py migrate

然后您可以将以下自定义添加到您的 admin.py:

  • 覆盖 get_urls 方法并在模型管理中添加 enable_descriptiondisable_discription 方法。它们将作为两种视图方法:

      def get_urls(self):
          urls = super().get_urls()
          my_urls = [ 
              path('descriptionon/', self.enable_description),
              path('descriptionoff/',self.disable_discription),
          ]
          return my_urls + URLs 
    
      def enable_description(self, request):
          self.model.objects.all().update(is_description=True)
          self.message_user(request, "All descriptions are now turned on")
          return HttpResponseRedirect("../") 
    
      def disable_description(self, request):
          self.model.objects.all().update(is_description=False)
          self.message_user(request, "All descriptions are now turned on")
          return HttpResponseRedirect("../")
    

接下来,您需要通过创建模板文件 product_changelist.html 覆盖 Django 管理模板,然后扩展 admin/change_list.html:

{% extends 'admin/change_list.html' %}

{% block object-tools %}
    <div>
        <form action="descriptionoff/" method="POST">
            {% csrf_token %}
                <button type="submit">Turn description on</button>
        </form>
        <form action="descriptionoff/" method="POST">
            {% csrf_token %}
                <button type="submit">Turn description off</button>
        </form>
    </div>
    <br />
    {{ block.super }}
{% endblock %}

访问您的 Product 模型的管理仪表板。您现在应该会在搜索栏上方看到两个按钮。

最后,在您的 views.py 中添加此逻辑:

def product_list(request):
    products = Product.objects.all()
    for product in products.iterator():    
    if product.is_description:
        return render(request,
                      'product_list.html',
                      {'product': products})
    disable_descp = product.__class__.objects.all().values('category', 'name', 'image',...)

    return render(request,
                  'product_list.html',
                  {'product': disable_descp})

当您在管理仪表板中单击 Turn description on 并刷新您的模板页面时,描述将可用。如果您在管理仪表板中单击 Turn description off,它将不可用。