Home > Net >  How to pre-fill a field in a ModelForm with the field's default value and not include it in the
How to pre-fill a field in a ModelForm with the field's default value and not include it in the

Time:08-20

I have a Post model which has a field called author, I was able to set the current user as it's default, But when I'm trying to not include it in the form related to it, It fails and gives me different errors. Here's the code:

models.py:

def get_file_path(instance, filename):
    file_extension = filename.split('.')[-1]
    return f'user_{instance.author}/{instance.pub_date.strftime("%Y/%B/%a-%M")}/logo.{file_extension}'


class Post(models.Model):
    title = models.CharField(max_length=75)
    body = models.TextField()
    logo = models.ImageField(upload_to=get_file_path, blank=True)
    author = models.ForeignKey(User, default=get_user_model(), on_delete=models.CASCADE)
    pub_date = models.DateTimeField(default=datetime.now())

forms.py:

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('title', 'body', 'author', 'logo')

        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control bg-dark border border-secondary text-light'}),
            'body': forms.Textarea(attrs={'class': 'form-control bg-dark border border-secondary text-light'}),
            'author': forms.Select(attrs={'class': 'form-control bg-dark border border-secondary text-light'}),
            'logo': forms.ClearableFileInput(attrs={'class': 'form-control bg-dark border border-secondary text-light'}),
        }

views.py:

class PostCreateView(LoginRequiredMixin, CreateView):
    login_url = 'login'
    model = Post
    form_class = PostForm
    template_name = "posts/new_post.html"

How can I not include the field in the form and the page, But have it use it's own default value?
NOTE that I don't want to create a field and make it hidden!

CodePudding user response:

Maybe remove author from PostForm and in PostCreateView:

class PostCreateView(LoginRequiredMixin, CreateView):
    login_url = 'login'
    model = Post
    form_class = PostForm
    template_name = "posts/new_post.html"
    
    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.author = self.request.user
        self.object.save()
        return HttpResponseRedirect(self.get_success_url())

EDIT: I don't think that passing get_user_model() as default in foreginkey field will work. This method will return the currently active user model, as django docs explain, but you need as defaut user object or id, so it should be:

author = models.ForeignKey(User, default=1, on_delete=models.CASCADE)

In that case you only need to remove field author from PostForm, you don't need to assign request.user in form_valid method of PostCreateView.

  • Related