Home > Software engineering >  When I pass a url parameter to modelform, None is passed instead of the url parameter
When I pass a url parameter to modelform, None is passed instead of the url parameter

Time:10-01

I am trying to build up a posting webpage.

This is how it works:
you click a button, the posting form will appear, you fill in the form, you click the submit button, and the process is complete. And when the form is submitted, a url parameter will be passed as the value of a hidden input in the modelform in the views.py.

However, when I browse the model in manage.py shell, None is saved instead of the url parameter.

Here are the codes:
models.py

from django.db import models
from django.db.models import CharField, TextField, DateField

class Post(models.Model):
    username = CharField(max_length=30, blank=True, null=True)
    content = TextField()
    dt_created = DateField(auto_now_add=True)
    dt_modified = DateField(auto_now=True)

    def __str__(self):
        return self.username

forms.py

from django import forms
from django.forms import Textarea, HiddenInput
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['content', 'username']
        widgets = {
            'content': Textarea(attrs={
                'class': 'write_input',
                'placeholder': 'write your story here...'
            }),
            'username': HiddenInput(attrs={
                'value': ' '
            })
        }
        labels = {
            'content': ''
        }

urls.py

from django.urls import path, include
from . import views

urlpatterns = [
    path('<str:username>/main/', views.account_main, name='account_main')
]

views.py

from django.shortcuts import render, redirect
from .forms import PostForm
from .models import Post

def account_main(request, username):
    context = dict()
    if request.method == 'POST':
        form = PostForm(request.POST, initial={'username': username})
        if form.is_valid():
            form.save()
            return redirect('account_main', username=username)
    form = PostForm()
    posts = Post.objects.all().order_by('dt_created')

    context['username'] = username
    context['form'] = form
    context['posts'] = posts
    return render(request, 'Account/account_main.html', context=context)

What I have tried:
Passing initial={'username': username} as kwargs to PostForm(),
Accessing cleaned_data and passing the url parameter as value like: form.cleaned_data['username'] = username

I could not find any solution for the issue in Google or Stack Overflow so far. Thank you in advacnce for your answer!!

CodePudding user response:

I found the solution.

After form.is_valid() returns True, I save the form by form = form.save(commit=False).
Then, I pass the url parameter as the value for form.username. Finally, I save the form by form.save().
When I browse the model, the url parameter is saved well as the username value.

Here is the code after I modified it:

def account_main(request, username):
    context = dict()
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form = form.save(commit=False)
            form.username = username
            form.save()
            return redirect('account_main', username=username)

CodePudding user response:

If your main motive is to pass a hidden field along with a form you can directly send without including it in the URL. And you can get files by

-->request.POST.get(#fieldName)

  • Related