I need to store an instance of the model in the database based on the POST data of the form, but with the condition thatauthorI take not from the form (and I don’t even display such a field in the form), but fromrequest.user.

The documentation () suggests a solution:

form= PartialAuthorForm(request.POST)
author= form.save(commit=False)
author.title= 'Mr'

How to reproduce the example in the console is clear, but where exactly in my application should I implement such logic? And how to pass request.user to the form?

Here are the main application files:


class Post(models.Model):
    event_describe= models.TextField(max_length=2000)
    event_location= models.CharField(max_length=50)
    author= models.ForeignKey(User, on_delete=models.PROTECT)
tags= models.ManyToManyField(Marker)
class Marker(models.Model):
    author= models.ForeignKey(User, on_delete=models.PROTECT)


class CreatePostForm(ModelForm):
    class Meta:
        model= post
        fields= ('event_describe', 'event_location')


class PostCreateView(CreateView):
    template_name= 'add_post.html'
    form_class= CreatePostForm
    success_url= reverse_lazy('posts')
    def get_context_data(self, **kwargs):
        context= super().get_context_data(**kwargs)
        context['author']= self.request.user
        return context

Please edit the question to reflect the specific problem with enough detail to be able to give an adequate answer.

Дух сообщества2022-02-12 20:54:14

Welcome! You've framed the question beautifully, but SO uses a model where one question contains one specific problem, and if you have a series of questions, then a separate one is created for each. My suggestion to you is to split the question into two. Although the first answer is obviously in a function located in views.py, request.user is not passed to the form, but is the entity of the authorized user currently on the page

Dmitry2022-02-12 20:54:14

Yes, indeed, this is my first experience. @Dmitry, can you clarify which function in PostCreateView should I override in this case?

Seb2022-02-12 20:54:14

Possible duplicate of question: Django substitute username in form automatically

Sherlock2022-02-12 20:54:14
  • Answer # 1

    Looks like you figured it out

    We need to override the PostCreateView form_valid() method, which calls (in case the form data is successfully validated) form.save() to save the model instance.

    Here you can change the default view logic. In my case, this is how it works:

    def form_valid(self, form):
            """If the form is valid, firstly save with commit=False argument the associated model."""
            self.object= form.save(commit=False)
            self.object.author= self.request.user
            # return form_valid ancestor
            return super().form_valid(form)
            # or we form the response ourselves
            #return HttpResponseRedirect(self.get_success_url())

    It's strange that the official documentation doesn't mention this...

  • Answer # 2

    In the view function, write something like

    if request.method== 'POST':
            obj.author='new author'

    In the view function, create a new model object with data from the post method, then change the desired characteristic and save, not forgetting the validation

    It turns out that I should prevent CreatePostForm from calling the save() method, which is responsible for saving the current model instance in the database, and do it on the PostCreateView side? Which view function should I override to follow the new model object creation algorithm?

    Seb2022-02-12 20:54:14

    a function that accepts post data, that is, the one to which the form is sent

    ganz2022-02-12 20:54:14

    creates and accepts data from the PostCreateView form: urlpatterns= [ path('add/', PostCreateView.as_view(), name='add'), ] And where to dig further?

    Seb2022-02-12 20:54:14