Djanga admin custom list_diplay - django

In the Django admin panel, how do I change admin.py so that each staff can see only their data in the list_display.
For example, there is a news site. 2 staffs will add news to the site. A separate account is opened for each staff. Only the news added by that staff should appear in the list of added news. This is how it is done in list_display? Please help.

Override get_queryset in the ModelAdmin for your model
class NewsAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.filter(added_by=request.user)

Related

Load external data into an admin model - DJANGO

Is it possible to load external data into a field for filling in?
Example: A field with for product names. However we already have the names of the products in another location, we just need to list these products within the field in the default django admin. Using resquets.
Thank you very much for your attention.
I think what you're looking for is how to customize the Django Admin, right? Check out this page in the documentation for a more detailed explanation, but here's an example that might help:
from django.contrib import admin
from .models import *
class ProductInline(admin.TabularInline):
model = Product
extra = 0
class OrderAdmin(admin.ModelAdmin):
inlines = [ProductInline]
admin.site.register(Order, OrderAdmin)
admin.site.register(Product)
This will show all of the products attached to a particular order when viewing that order from Django Admin.
You can prepopulate/fill a field in Django Admin with external data source. I guess you have some options defined somewhere outside your Django app and use those options as input for a charfield/integer field.
You can handle filling choices in a seperate Django form or overriding ModelAdmin methods. By creating a seperate form:
filter_choices = depends on your logic for loading external data
class AdminForm(forms.ModelForm):
filter_text = forms.ChoiceField(choices = filter_choices , label="Filter By",
widget=forms.Select(), required=True)
class Meta:
model = YourModel
#admin.register(YourModel)
class YourModelAdmin(admin.ModelAdmin):
form = AdminForm
You can try the 'formfield_for_foreignkey' method of the default ModelAdmin class
Example:
class MyModelAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "car":
kwargs["queryset"] = Car.objects.filter(owner=request.user)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
This example (from the original docs) will populate the 'car' field with only specific values.
Pls note that this method suits a foreinKey. I'm not sure if it fits your requirements.

Django Admin: Restrict staff to update

I had a Blog Model. All new blog post has DRAFT status.
In the admin page, admin would be all permissions (CRUD) on the Blog Model. I can solve this by using Django's register method.
What I want is is_staff user can view all the Blog Post but can't update Status (Eg. from DRAFT to APPROVE).
Is there any way to check the request's group, then allow the user to update or not? Thanks.
The simplest solution is to mark the status field as read only in the admin class, by setting readonly_fields:
from django.contrib import admin
from .models import BlogPost
#admin.register(BlogPost):
class BlogPostAdmin(admin.ModelAdmin):
readonly_fields = ('status',)
Note that this makes status read-only for ALL admin users. If you need more fine-grained control based on the current user, there is a get_readonly_fields method you can override.
Also, since ALL users of the Django Admin have is_staff, we'll explicitly check for the built-in permission to change a BlogPost.
class BlogPostAdmin(admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
# obj is None if we're creating a new BlogPost, or a BlogPost instance
# if we are editing an existing BlogPost
if not request.user.has_perm("your_app.change_blogpost"):
return ("status",)
return []

Is there a way to have a field that only the superuser can add/edit?

Is there a way to have a field that only the superuser can add/edit?
class ProductPage(Page):
price = models.IntegerField(blank=True)
description = RichTextField(blank=True)
featured = models.BooleanField(default=False)
Above is part of my model but i only want the superuser to access the featured field.
I'm assuming you mean that only superusers logged in the Django admin site should be able to edit the featured field. If you want to restrict access in your own forms and views, you just need to check the user's status and customize the form/view accordingly. Here's what you can do in admin.py, in your ModelAdmin:
def get_readonly_fields(self, request):
fields = super().get_readonly_fields(request)
if not request.user.is_superuser:
fields.append('featured')
return fields
I tried out the solution given by #dirkgroten but had to make a few changes to make it work.
According to the Django Documentation for >2.1 versions of Django, the get_readonly_fields take 3 parameters.
Also, fields need to set a list to append, as it creates a tuple on default.
def get_readonly_fields(self, request, obj=None):
fields = list(super().get_readonly_fields(request))
if not request.user.is_superuser:
fields.append('featured')
return fields

Django admin interface

Is it possible to display in admin interface objects that related to the current user?
For example:
class Feedback(models.Model):
to = models.ForeignKey(User)
message = models.CharField(max_length=200)
I have several admins and I want to display messages to the related admin. Thank you!
You can customize your admin site by putting a file named admin.py in your application directory, writing a ModelAdmin class for your model and overriding its queryset method, like this:
class FeedbackModelAdmin(admin.ModelAdmin):
fields = ('message',)
def queryset(self, request):
qs = super(FeedbackModelAdmin, self).queryset(request)
return qs.filter(to=request.user)
Check the full documentation of the Django admin site.

Auto-populating user manytomanyfield with Django admin site

I have a class Business, example:
class Business(models.Model):
users = models.ManyToManyField(User)
business_name = models.CharField(max_length=100)
So the variable users in connected with the User. And let's assume that in the User, there are 5 users were created: Admin, Test, Test1, Test2 and Test3. So only Admin is the superuser of all the users and let's say that I am logged in using Test2. So when I clicked save, the manytomanyfield will be automatically saved with Test2, so it is like automatically saved on whoever the request.user is.
And also, is there a way to automatically save all the users in the manytomanyfield? thanks.
You don't need to use JavaScript for this, neither do you need to show a form field for users if it's meant to be automatically updated. You can instead create a ModelAdmin subclass and override the save_model method. For example:
In the admin.py of your app
from django.contrib import admin
from models import Business
class BusinessAdmin(admin.ModelAdmin):
exclude = ["users"]
def save_model(self, request, obj, form, change):
if not obj.id: obj.save()
obj.users.add(request.user)
obj.save()
admin.site.register(Business, BusinessAdmin)