Django admin show only current user for User field as ForeignKey while creating and object

367 Views Asked by At

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?

2

There are 2 best solutions below

2
willeM_ Van Onsem On BEST ANSWER

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)
0
weAreStarsDust On

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)