Django admin show only current user for User field as ForeignKey while creating and object
Question:
I’m working on a Django ( 4.0 +) project, where I have a model named Post
in which we have a ForignKey field as Author
, a user with is_staff
and in Authors
group can create an object of Post
from admin.
Now the problem is when user click on Add Post
as the Author
field it should only display the current user not the others.
Here’s what i have tried:
From models.py
:
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
thumbnail = models.ImageField()
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, related_name='category')
featured = models.BooleanField()
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
From admin.py
:
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'status','created_on')
list_filter = ("status",)
search_fields = ['title', 'content']
prepopulated_fields = {'slug': ('title',)}
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)
How can I achieve that?
Answers:
I would advise to simply exclude the field from the form, and assign the user when you save the model with the .save_model(…)
method [Django-doc]:
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'status', 'created_on')
list_filter = ('status',)
search_fields = ['title', 'content']
prepopulated_fields = {'slug': ('title',)}
exclude = ('author',)
def get_queryset(self, request):
qs = super().get_queryset(request)
if not request.user.is_superuser:
qs = qs.filter(author=request.user)
return qs
def save_model(self, request, obj, form, change):
obj.author = request.user
return super().save_model(request, obj, form, change)
Try formfield_for_foreignkey()
It overrides the default formfield for a foreign keys field. In your case, to return only current user for author
foreign key field:
class PostAdmin(admin.ModelAdmin):
...
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'author':
kwargs['queryset'] = User.objects.filter(id=request.user.id)
return super().formfield_for_foreignkey(db_field, request, **kwargs)
I’m working on a Django ( 4.0 +) project, where I have a model named Post
in which we have a ForignKey field as Author
, a user with is_staff
and in Authors
group can create an object of Post
from admin.
Now the problem is when user click on Add Post
as the Author
field it should only display the current user not the others.
Here’s what i have tried:
From models.py
:
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
thumbnail = models.ImageField()
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, related_name='category')
featured = models.BooleanField()
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
From admin.py
:
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'status','created_on')
list_filter = ("status",)
search_fields = ['title', 'content']
prepopulated_fields = {'slug': ('title',)}
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)
How can I achieve that?
I would advise to simply exclude the field from the form, and assign the user when you save the model with the .save_model(…)
method [Django-doc]:
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'status', 'created_on')
list_filter = ('status',)
search_fields = ['title', 'content']
prepopulated_fields = {'slug': ('title',)}
exclude = ('author',)
def get_queryset(self, request):
qs = super().get_queryset(request)
if not request.user.is_superuser:
qs = qs.filter(author=request.user)
return qs
def save_model(self, request, obj, form, change):
obj.author = request.user
return super().save_model(request, obj, form, change)
Try formfield_for_foreignkey()
It overrides the default formfield for a foreign keys field. In your case, to return only current user for author
foreign key field:
class PostAdmin(admin.ModelAdmin):
...
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'author':
kwargs['queryset'] = User.objects.filter(id=request.user.id)
return super().formfield_for_foreignkey(db_field, request, **kwargs)