2

I have the following ModelForm:

class IssueProcessForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(IssueProcessForm, self).__init__(*args, **kwargs)

        self.fields['number'].disabled = True
        self.fields['title'].disabled = True
        self.fields['body'].disabled = True

        self.fields['body'].widget = forms.Textarea(
            attrs={
                'cols': 50
            }
        )

    class Meta:
        model = Issue
        fields = (
            'number', 'title', 'body', 'price'
        )

I want to pre-populate the fields number, title, and body with data from within a view, render the form, and make sure value corresponding to the fields show while also disabling these fields, so that user won't alter values. I want the price field to be the only thing a user touches and when the save button is clicked, I want everything saved to the database. I tried the following:

def issue_process(request, repo_name, issue_number):
    get_issue_number = request.session.get('issue_number_{}'.format(issue_number))
    get_issue_title = request.session.get('issue_number_{}_title'.format(issue_number))
    get_issue_body = request.session.get('issue_number_{}_body'.format(issue_number))

    if request.method == 'POST':
        form = IssueProcessForm(request.POST)
        if form.is_valid():
            issue = form.save(commit=False)
            issue.number = get_issue_number
            issue.title = get_issue_title
            issue.body = get_issue_body
            issue.save()
    else:
        form = IssueProcessForm(initial={
            'number': get_issue_number,
            'title': get_issue_title,
            'body': get_issue_body
        })
    return render(request, 'core/issue_process.html', {'form': form})

...but each of the three fields keep saying this field is required when I try submitting. What can I do please? Please note that get_issue_number, get_issue_title, get_issue_body are the values I'd like to pre-populate the fields number, title, and body with, respectively.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
Caspian
  • 633
  • 1
  • 10
  • 29

1 Answers1

6

When you disable a form field, the browser does not submit the field's value when you submit the form. Therefore you need to provide the initial data for POST requests as well as GET requests:

if request.method == 'POST':
    form = IssueProcessForm(
        request.POST,
        initial={
            'number': get_issue_number,
            'title': get_issue_title,
            'body': get_issue_body
        },
    )
    ...
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • This works, thanks! But I want to disable those fields because I don't want users tampering with the value. I also have to show those fields. How do you think I can achieve this? – Caspian Oct 31 '18 at 13:30
  • 1
    I don't understand your question. You *have* disabled the fields in the form, e.g. by setting `self.fields['number'].disabled = True`. My changes above are in the view so they don't affect whether or not the fields are disabled in the form. – Alasdair Oct 31 '18 at 15:52