Zorgan
Zorgan

Reputation: 9123

initial value for ModelForm field not working

I'm tring to set the user field as the logged-in user, but it's returning None. Here's my model:

class Post(models.Model):
    user = models.ForeignKey(User, blank=True, null=True)
    title = models.TextField(max_length=76)
    date = models.DateTimeField(auto_now=True)
    content = models.TextField(null=False, default='')
    image = models.FileField(null=True, blank=True)
    category = models.CharField(max_length=20, choices=CATEGORY_CHOICES, default='1')

my form:

class PostForm(forms.ModelForm):
    content = forms.CharField(widget=PagedownWidget)
    title = forms.TextInput(attrs={'placeholder': 'title'})

    class Meta:
        model = Post
        fields = [
            'title',
            'content',
            'category',
            'image',
            'id',
            'user'
        ]

and my view where users make a post using a form:

def post(request):
    allauth_login = LoginForm(request.POST or None)
    allauth_signup = SignupForm(request.POST or None)
    if request.user.is_authenticated():
        data = {'user': request.user}
        form_post = PostForm(request.POST, request.FILES, initial=data)
        if form_post.is_valid():
            category = form_post.cleaned_data['category']
            for a, b in CATEGORY_CHOICES:
                if a == category:
                    category = b
                    form_post.save()
            return HttpResponseRedirect('/%s' % category)
        else:
            form_post = PostForm()

        context = {
            'allauth_login': allauth_login,
            'allauth_signup': allauth_signup,
            'form_post': form_post
        }

        return render(request, 'post.html', context)
    else:
        return HttpResponseRedirect("/accounts/signup/")

When I actually render the form in my template, {{ obj.user }}returns None. Any idea why?

{% for obj in Post.objects.all() %}
    {{ obj.title }} #works
    {{ obj.content }} #works

    ...

    {{ obj.user }} #does not work

{% endfor %} 

Upvotes: 2

Views: 2392

Answers (2)

neverwalkaloner
neverwalkaloner

Reputation: 47354

You are initializing form incorrectly. If request method is not POST form will contain errors.

Try this:

form_post = PostForm(request.POST or None, request.FILES or None, initial=data) 

UPDATE

You can also try to do it this way. Remove user field from form and in view do this:

if form_post.is_valid():
    instance = form_post.save(commit=False)
    instance.user = request.user
    instance.save()   

Upvotes: 3

YKL
YKL

Reputation: 542

I think you mixed up with initial and bound form with data. In your case, I'm guessing you're trying to save post with valid user first, and then redirect to the page to show the new post with user.

So it should be:

def post(request):
    allauth_login = LoginForm(request.POST or None)
    allauth_signup = SignupForm(request.POST or None)
    if request.user.is_authenticated():
        data = request.POST.copy()
        data['user'] = request.user
        form_post = PostForm(data, request.FILES)
        if form_post.is_valid():
            category = form_post.cleaned_data['category']
            for a, b in CATEGORY_CHOICES:
                if a == category:
                    category = b
                    form_post.save()
            return HttpResponseRedirect('/%s' % category)
        else:
            form_post = PostForm()

        context = {
            'allauth_login': allauth_login,
            'allauth_signup': allauth_signup,
            'form_post': form_post
        }

        return render(request, 'post.html', context)
    else:
        return HttpResponseRedirect("/accounts/signup/")

For initial -- These values are only displayed for unbound forms: https://docs.djangoproject.com/en/1.10/ref/forms/api/#django.forms.Form.initial

Upvotes: 0

Related Questions