DjangoRulz
DjangoRulz

Reputation: 95

How to assign HTML Form fields to DJANGO Model Forms without using ModelForm

I am trying to make pretty looking HTML form where each fields are formatted with some validation and icons. Once these fields are submitted I want to save to Model instance using either using Model form or some other approach which allows to make this operation smooth.

Here is my code snippet: model.py:

class Client(Model):    
    client_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    first_name = models.CharField(max_length=256)
    last_name = models.CharField(max_length=256)
    date_of_birth = models.DateField(blank=True, null=True)
    email = models.EmailField(null=True)

form.py:

class ClientNewForm(forms.ModelForm):
    class Meta:
        model = Client    
        fields = "__all__"

view.py (I know this is wrong but need help to figure out what's the best way to do this):

class ClientCreateView(CreateView):
    model=Client
    form_class = ClientNewForm
    template_name = 'Client/client_new.html'
    
    context_object_name = 'client' # refer the object as patient in template
    success_url = reverse_lazy('WebApp:clients')

        
    def form_valid(self, form):
        model = form.save(commit=False)
        #model.submitted_by = self.request.user
        model.save()
        messages.success(self.request, "The Client is created successfully.")
        return super(ClientCreateView, self).form_valid(form)

Template:

<div class='row'>
    <div class="col-md-8 col-sm-8 col-xs-12">
        <div class="x_panel">
        <div class="x_title">
            <h2>NEW REGISTRATION</h2>
        </div>
        <div class="x_content">
            <form class="form-horizontal form-label-left input_mask" action="" method="post"> 
                {%  csrf_token %}
                <div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
                    <input type="text" class="form-control has-feedback-left" id="in-fn" placeholder="First Name" name="first_name">
                    <span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
                </div>

                <div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
                    <input type="text" class="form-control has-feedback-left" id="in-ln" placeholder="Last Name" name="last_name">
                    <span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
                </div>

                <div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
                    <input type="text" class="form-control has-feedback-left"  id="in-dob" name="date_of_birth" placeholder="Date of Birth (mm/dd/yyyy)" >
                    <span class="fa fa-calendar form-control-feedback left" aria-hidden="true"></span>
                </div>

                <div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
                    <input type="text" class="form-control has-feedback-left" id="in-email" placeholder="Email" name="email">
                    <span class="fa fa-envelope form-control-feedback left" aria-hidden="true"></span>
                </div>

                <div class="form-buttons">
                    <div class="col-md-9 col-sm-9 col-xs-12 col-md-offset-9">
                    <a href="{% url 'WebApp:clients' %}" type="button" class="btn btn-round btn-danger">Cancel</a>
                    <a href="{% url 'WebApp:client-new' %}" type="button" class="btn btn-round btn-warning">Reset</a>
                    <input type="submit" value="Save" class="btn btn-round btn-success"/>
                    </div>
                </div>

            </form>
        </div>
    </div>
</div>

So I need help from Django Experts to make this work properly. If possible can you please help me to figure out following:

  1. Can I make each Django Field as individual formatting filed (I like to format each fields better than crispy forms)? (I am using gentelella templates).
  2. What would be best way to get each fields assign back to model fields and save in database? Current approach I am taking is Django Model form but I am not sure if this right approach for me to achieve what I am trying to do.

Really appreciate your help and consideration.

Thank You.

Upvotes: 0

Views: 111

Answers (1)

DjangoRulz
DjangoRulz

Reputation: 95

I used django-wiget-tweaks library to get me through this problem. Its super Easy and it works like charm to help me customize the form look and feel.

Here are steps I followed:

step 1: install: pip install django-widget-tweaks on my virtual environment

Step 2: update settings.py for INSTALLED_APPS = [ 'widget_tweaks']

Step 3: on my template I had to put following at the top of the Template: {% load widget_tweaks %}

Step 4: Now I can use the renderfields to do this all stuff as follow:

<div class='row'>
    <div class="col-md-8 col-sm-8 col-xs-12">
        <div class="x_panel">
        <div class="x_title">
            <h2>NEW REGISTRATION</h2>
        </div>
        <div class="x_content">
            <form class="form-horizontal form-label-left input_mask" action="" method="post"> 
                {%  csrf_token %}
                <div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
                    {% render_field form.first_name class="form-control" placeholder="First Name"|append_attr:"required" %}
                    <span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
                </div>

                <div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
                    {% render_field form.last_name class="form-control" placeholder="Last Name" %}
                    <span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
                </div>

                <div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
                    {% render_field form.date_of_birth class="form-control" placeholder="Date of Birth (mm/dd/yyyy)"%}
                    <span class="fa fa-calendar form-control-feedback left" aria-hidden="true"></span>
                </div>

                <div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
                    {% render_field form.email class="form-control has-feedback-left" placeholder="Email Address" %}
                    <span class="fa fa-envelope form-control-feedback left" aria-hidden="true"></span>
                </div>

                <div class="form-buttons">
                    <div class="col-md-9 col-sm-9 col-xs-12 col-md-offset-9">
                    <a href="{% url 'WebApp:clients' %}" type="button" class="btn btn-round btn-danger">Cancel</a>
                    <a href="{% url 'WebApp:client-new' %}" type="button" class="btn btn-round btn-warning">Reset</a>
                    <input type="submit" value="Save" class="btn btn-round btn-success"/>
                    </div>
                </div>

            </form>
        </div>
    </div>
</div>

Step 5: On view now I can use CreateView, UpdateView, ListView with Modelforms.

So far it works for me.

I hope this helps to other member who is looking to be creative with their forms.

Upvotes: 0

Related Questions