Reputation: 421
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
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
Reputation: 1929
Several ways to do so.
1 permission to admin user. 2 bool show or not to Object. 3 New Admin view.
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
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)
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
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