Will
Will

Reputation: 11500

Django Template render dictionary values into html form using Function Based View

Summary

Using Django 1.8, I'm trying to make a Function Based View that renders an html page that allows me to update the contents of the object. I'm able to get this to work by using the form.as_p as shown in the documentation here, but I can't get these values inside an html <input> as the value.

Issue

The issue is that only the first word appears and the rest of the text is cut off (e.g. for a html input tag, the value of 'Hello World Will' gets turned into 'Hello')

model.py

class Questions(model.Model):
    title = models.CharField(max_length=512, null=False, blank=False)

forms.py

class QuestionsForm(forms.ModelForm):
    class Meta:
        model = Questions
        fields = ('title', )

views.py

def advice_update(request, pk)
    question_results = Questions.object.get(id=pk)
    advice_form = QuestionsForm(request.POST or None, instance=question_results)
    ...
    return render(request, 'advice/advice_update.html', {'advice_form': advice_form, 'question_results': question_results,})

advice_update.html

<form method='POST' action=''>{% csrf_token %}

# METHOD 1 - This code works and renders the form with paragraphs enclosed
# but I want more control
{{ advice_form.as_p }}

# METHOD 2 - When I try to get the value by itself, it works too
{{ advice_form.instance.title }}  # E.g. 'Hello World'
{{ question_results.title }}  # E.g. 'Hello World'

# METHOD 3 - When I try to put the text inside a 'value' tag in an 'input', 
# the text gets cut off and only the first word appears in the input
# When I look at the console, I see the rest of the text in there.
<input id="id_title" type="text" name="title" class="form-control" value={{ question_results.title }}>

I tried a few things like adding autoescape and safe tags, but when I use METHOD 3, the value inside the tag of advice.html cuts off when there's a space (e.g. 'Hello World' turns into 'Hello').

Upvotes: 0

Views: 930

Answers (1)

Brandon Taylor
Brandon Taylor

Reputation: 34593

First, you don't need to set null=False, blank=False on your title field as those are there by default.

It looks like the main issue you're having is adding the Bootstrap css class to the form element, which you can accomplish a couple of different ways. Also note that your value attribute is missing quotes around it.

The first way is to add the appropriate classing to the widget from the Python side of the form:

class QuestionsForm(forms.ModelForm):
    class Meta:
        model = Questions
        fields = ('title', )

        def __init__(self, *args, **kwargs):
            super(QuestionsForm, self).__init__(*args, **kwargs)
            self.fields['title'].widget.attrs['class'] = 'form-control'

However, this gets really tedious when you're dealing with a lot of form fields. So, I use django-widget-tweaks to instead add these at the template level:

{{ form.title|add_class:"form-control" }}

which I find a lot easier to deal with. This way you don't have to render the field by hand. Also be sure to handle the case if there's no matching question in your view:

question = get_object_or_404(Question, id=pk)

Upvotes: 1

Related Questions