2

So I have the following user registration form which I want to style. My forms.py look something like this. :

from django.contrib.auth.models import User
from django import forms

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())

    class Meta:
        model = User
        fields = ['username','email','password']

Now this is my views.py:

class UserFormView(View):
    form_class =UserForm
    template_name = 'visit/registration/register.html'

    def get(self,request):
        form = self.form_class(None)
        return render(request,self.template_name,{'form':form})

    def post(self, request):
        form = self.form_class(request.POST)

        if form.is_valid():

            user =form.save(commit=False)

            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            user.set_password(password)
            user.save()

            user = authenticate(username=username, password=password)

            if user is not None:

                if user.is_active:
                    login(request,user)
                    return redirect('visit:index')


        return render(request, 'visit/registration/register.html', {'form': form})

Now What I am getting a bit confused in HTML, since there is only one line which passes all these fields in the page together. So how M I supposed to style these fields separately.

{% extends 'visit/base.html'%}

{%block content%}
<!DOCTYPE html>
<html>
{% load staticfiles %}
<link rel = "stylesheet" type = "text/css" href = "{% static "visit/registration.css"%}">
<head>
    <title></title>
</head>

<body>
    <form method="POST" class = "sign-up-form">
        {% csrf_token %} {{ form.as_p }}
        <button type="submit">Submit</button>
    </form>
</body>

</html>
{%endblock%}

2 Answers2

1

You can simply use django-bootstrap
This will automatically render the bootstrap form for you.

{% extends 'visit/base.html'%}
{% load bootstrap3 %}

{%block content%}
<!DOCTYPE html>
<html>
{% load staticfiles %}
<link rel = "stylesheet" type = "text/css" href = "{% static "visit/registration.css"%}">
<head>
    <title></title>
</head>

<body>
    <form method="POST" class = "sign-up-form">

        {% csrf_token %} 
        {% bootstrap_form form %}

        <button type="submit">Submit</button>
    </form>
</body>

</html>
{%endblock%}
Aokiji
  • 50
  • 1
  • 1
  • 9
0

You have multiple options, each one with its pros and cons:

1. Add custom css classes within forms.py

To use the simplicity of {{ form.as_p }} approach you could manually add classes to all your forms fields, e.g.:

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput(
        attrs={'class' : 'your-custom-class'})
    )

Note that it could be a challenge to render the form to be perfectly aligned with Bootstrap's style.

2. Render the form manually

You could write your form by hand within your template, e.g.:

<div class="form-group">
  <label for="{{ form.password.id_for_label }}">
    {% trans 'Password' %}
  </label>
  <input type="text" id="{{ form.password.id_for_label }}"
         name="{{ form.password.html_name }}"
         {% if form.password.field.required %}required{% endif %}
         class="form-control{% if form.password.errors %} is-invalid{% endif %}"
         value="{% if form.password.value %}{{ form.password.value }}{% endif %}">
  {% if form.password.help_text %}
    <small class="text-muted">
      {{ form.password.help_text }}
    </small>
  {% endif %}
  {% for err in form.password.errors %}
    <span class="invalid-feedback">{{ err }}</span>
  {% endfor %}
</div>

More info on rendering form fields manually can be found here.

The above snippet will use most of the functionality existing in the default django form renders methods, but on the other hand forces you to write a lot of boilerplate code which is harden to maintain in the long run.

3. Use 3rd party app as a mix of the first two options

You could use custom app to handle the rendering of the forms, a good example would be django-crispy-forms.

bonidjukic
  • 1,461
  • 1
  • 13
  • 19