get current user for 'created_by' field in model class
Asked Answered
F

3

5

I'm currently working on a Django app, and I'm trying to set the current user as default on a model, but it doesn't work.

created_by = models.ForeignKey(User, default=request.user, null=True, blank=True, on_delete=models.DO_NOTHING, related_name='created_by')

I tried to override the save() method but it doesn't work either, anyone has any experience on this matter ?

Thanks a lot in advance for your help

Feodora answered 18/10, 2018 at 10:27 Comment(2)
You can't do that in the model at all. It needs to be done in the view. There are many previous questions on this, as well as an explicit explanation in the docs.Patty
@DanielRoseman The link to the docs you provided mentions that "In the view, ensure that you don’t include created_by in the list of fields to edit". Could you explain why that ? Because it seems to work even if you don't specify the fields variable.Amata
C
7

Refer official doc. It explained it pretty well. An example is also there

from django.views.generic.edit import CreateView
from myapp.models import Author

class AuthorCreate(CreateView):
    model = Author
    fields = ['name']

    def form_valid(self, form):
        form.instance.created_by = self.request.user
        return super().form_valid(form)

https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-editing/#models-and-request-user

Circinus answered 18/10, 2018 at 10:35 Comment(1)
The link to the docs you provided mentions that "In the view, ensure that you don’t include created_by in the list of fields to edit". Could you explain why that ? Because it seems to work even if you don't specify the fields variable.Amata
B
3

If your model is like below model.py

class Post(models.Model):
   title = models.CharField(max_length=500)
   created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null= True)

In model admin class in admin.py add the following method

class PostAdmin(admin.ModelAdmin):
    readonly_fields = ('created_by',)
    list_display = ('title', 'created_by')

    def save_model(self, request, obj, form, change):
        if obj.id == None:
           obj.created_by = request.user
           super().save_model(request, obj, form, change)

        else:

           super().save_model(request, obj, form, change)


admin.site.register(Post, PostAdmin)
Basinger answered 22/1, 2022 at 10:44 Comment(0)
F
1

If anyone encounters this problem I followed the advice of a_k_v and did it in views. Here is how I did it :

I added two fields in my class :

class Class(models.Model):
    created_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, blank=True, null=True, related_name='create')
    updated_by = models.ForeignKey(User, on_delete=models.DO_NOTHING, blank=True, null=True, related_name='update')

then created a function :

def created_updated(model, request):
    obj = model.objects.latest('pk')
    if obj.created_by is None:
        obj.created_by = request.user
    obj.updated_by = request.user
    obj.save()

to get it into my views.py :

    if request.method == 'POST':
    form = AddVacation(request.POST)
    if form.is_valid:
        form.save()
        created_updated(Vacation, request)
Feodora answered 18/10, 2018 at 13:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.