0

I am trying to retrieve an instance's current data to bootstrap form for update. When i use {{user_form.as_p}} all current data is filled automatically however replace it with bootstrap forms it seems empty. Here is my python and html files:

views.py

def update_profile(request):

   if request.method == 'POST':
        user_form = RegisterForm(request.POST, instance=request.user)
        if user_form.is_valid():
            user_form.save()
            return redirect('profile')

    else:
        user_form = RegisterForm(instance=request.user)

    return render(request, 'blog/update_profile.html', {
        'user_form': user_form,
    })

update_profile.html

<form method="post">
    {% csrf_token %}
    <div class="form-group">
      <label for="formGroupExampleInput">Name</label>
      <div id="formGroupExampleInput">
        <input class="form-control" name="first_name"  maxlength="150" autofocus required="" id="id_first_name" type="text" placeholder="First name" >
      </div>
    ...      
    <div class="form-group">
     <button type="submit" class="btn btn-success" id="formGroupExampleInput5">Save changes</button>
   </div>
</form>

forms.py

class RegisterForm(UserCreationForm):
   email = forms.EmailField(max_length=200, help_text='Required')

   class Meta:
        model = User
        fields = ('first_name', 'last_name', 'username', 'email', 'password1', 'password2')
ikonuk
  • 575
  • 8
  • 19
  • Where exactly do you render the form? – Willem Van Onsem Aug 28 '18 at 19:55
  • ... or to refine the question: did you put the {{user_form.as_p}} in the bootstrap template? – ger.s.brett Aug 28 '18 at 20:01
  • There is no problem with rendering i tested it. When i use `{{user_form.as_p}}` all data retrieved except password. If i use `{{user_form.first_name}}` it again works. But i can not integrate code in this input tag`` using `{{user_form.first_name}}`. @WillemVanOnsem – ikonuk Aug 28 '18 at 20:04
  • I can use but not in input tag.`value="{{user_form.first_name }}"` also does not work. @ger.s.brett – ikonuk Aug 28 '18 at 20:06
  • replace the input tag with {{user_form.as_p}} – ger.s.brett Aug 28 '18 at 20:11
  • I tried it works but not seem bootstrap's standart input style.`{{user_form.first_name}}` itself came as an input style, so i can not use it as a text. @ger.s.brett – ikonuk Aug 28 '18 at 20:15
  • Now you just need to add the class "form-control" to the field in the view - see https://stackoverflow.com/questions/5827590/css-styling-in-django-forms – ger.s.brett Aug 29 '18 at 04:58
  • Thank you @ger.s.brett I read the solution. – ikonuk Aug 29 '18 at 11:09

2 Answers2

2

I definitely think this is something everyone could benefit from. I presume you will probably be wanting to continue using bootstrap forms/designs for forms throughout, so the best way is to create another file where you do the magic from – and then reuse that every time. Here’s an example I got from here.

{% load widget_tweaks %}

{% for hidden_field in form.hidden_fields %}
  {{ hidden_field }}
{% endfor %}

{% if form.non_field_errors %}
  <div class="alert alert-danger" role="alert">
     {% for error in form.non_field_errors %}
      {{ error }}
    {% endfor %}
  </div>
{% endif %}

{% for field in form.visible_fields %}
  <div class="form-group">
    {{ field.label_tag }}

    {% if form.is_bound %}
      {% if field.errors %}
        {% render_field field class="form-control is-invalid" %}
        {% for error in field.errors %}
          <div class="invalid-feedback">
            {{ error }}
          </div>
        {% endfor %}
      {% else %}
        {% render_field field class="form-control is-valid" %}
      {% endif %}
    {% else %}
      {% render_field field class="form-control" %}
    {% endif %}

    {% if field.help_text %}
      <small class="form-text text-muted">{{ field.help_text }}</small>
    {% endif %}
  </div>
{% endfor %}

This is then passed through the template as follows (where the code above resides in the file named bs4_form.html):

<form method="post" novalidate>
  {% csrf_token %}
  {% include 'includes/bs4_form.html' with form=form %}
  <button type="submit" class="btn btn-primary">Submit</button>
</form>

Personally, I had issues rendering the errors, yet this can quickly be fixed by doing {{ error.as_p }} instead of {{ error }}. This also holds true for anything else which renders as code and note its proper form. Hope this helps!

Felix
  • 84
  • 9
  • Thank you @Felix that is great, even do not need to use a line for each field with for loop and it detects all area type itself. – ikonuk Aug 29 '18 at 10:35
0

For people who take my code as base for problem, here is the solution :

{% load widget_tweaks %}

  <form method="post" enctype= "multipart/form-data">
    {% csrf_token %}


    {% for hidden_field in user_form.hidden_fields %}
      {{ hidden_field }}
    {% endfor %}

    {% for field in user_form.visible_fields %}
      <div class="form-group">
        {{ field.label_tag }}
        {% render_field field class="form-control" %}
        {% if field.help_text %}
          <small class="form-text text-muted">{{ field.help_text }}</small>
        {% endif %}
      </div>
    {% endfor %}

      <button type="submit" class="btn btn-success" id="formGroupExampleInput5">Save changes</button>

    </div>
  </form>
ikonuk
  • 575
  • 8
  • 19