4

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

Theophile
  • 105
  • 1
  • 1
  • 8
  • 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](https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-editing/#models-and-request-user). – Daniel Roseman Oct 18 '18 at 10:32
  • @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. – Takamura Sep 24 '21 at 14:15

3 Answers3

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

a_k_v
  • 1,558
  • 7
  • 18
  • 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. – Takamura Sep 24 '21 at 14:09
2

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)
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)
Theophile
  • 105
  • 1
  • 1
  • 8