PercySherlock
PercySherlock

Reputation: 421

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

I want to implement a setting in my Django admin dashboard where I can disable/enable a particular field. If I should disable the field, the data in that field will not be rendered on the web page. If I should enable the field, then the data will be shown in the webpage. I only want to do this from my the admin dashboard.

This is my 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)

This is the 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',)}

I want to have the ability to enable/disable (maybe like a toggle button) the description field from my admin dashboard. Is there a way to implement this in my admin.py file? How can I go about this? Thanks.

Edit: For better understanding (as suggested the comment), I want to implement a master toggle in the admin dashboard which turns on/off all descriptions for every instance shown to the user.

Upvotes: 2

Views: 1305

Answers (3)

Toluwalemi
Toluwalemi

Reputation: 414

Here is what you can do:

First, add this field to your models.py:

is_description = models.BooleanField(default=True)

Then make migrations:

python manage.py makemigrations
python manage.py migrate

Then you can add the following customization to your admin.py:

  • override the get_urls method and add the enable_description and disable_discription methods on the model admin. They will serve as the two view methods:

      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("../")
    

Next, you need to override your Django admin template by creating a template file product_changelist.html and then extend 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 %}

Visit your admin dashboard for your Product model. You should now see the two buttons above the search bar.

Finally, in your views.py add this logic:

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})

When you click on Turn description on in your admin dashboard and refresh your template page, the descriptions will be available. It will not be available if you click on Turn description off in your admin dashboard.

Upvotes: 3

Ohad the Lad
Ohad the Lad

Reputation: 1929

Several ways to do so.

1 permission to admin user. 2 bool show or not to Object. 3 New Admin view.

1

You may add a permission to see this field and create a method in admin.py to see it or return None depending on permission value.

In admin.py in

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

You may add a bool to the object instead of permission to user (show or do not show in admin) and change the query set as in option 1 (this way you may control it from the client side FE)

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

3

Create anew Admin view NoFieldAdmin and alternative to Admin and show or not show the link in main admin via the admin url in main admin.py file

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),

Upvotes: 0

Jacinator
Jacinator

Reputation: 1413

The 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.

Upvotes: 0

Related Questions