oktested
oktested

Reputation: 81

Form data validation (equivalent of form.is_valid) in a Django consumer (Django Channels)

I'm moving from an http-based setup (Django forms, views etc) to a websocket setup using Django Channels (reasons unavoidable). In my http-based setup, I was entering some data using a form (3 fields - name, number, city) in my template:

<form id="EntryForm" method="POST">
      {% csrf_token %}
      <div class="form-group ">
        {{ form }}
      </div>
      <button type="submit">Submit</button>
</form>

Since this data was being submitted as a Django form previously (which was mapped to my Django model using "class Meta:"), I was easily able to validate it in my views.py using the form.is_valid() method. Each field in the form data has certain conditions like CharField (max_length) etc which was getting verified by the is_valid() method in my views.py:

if request.method == 'POST':
    form = EntryForm(request.POST, instance=Entry(user=request.user))
    if form.is_valid():
        form.save()
        messages.success(request, f'Submission accepted.')
...

As you can see above, the form belongs to a form class "EntryForm" in my forms.py, which maps to a model called Entry in my models.py (which contains fields like name, number and city).

But in Django Channels, in order to submit form data, since I'm having to use a script to .preventDefault() and then send the data as a separate dictionary to my consumers.py, it doesn't get there as a Django form. Here is my script:

<script>
$(document).ready(function(){

    var form_data = $("#EntryForm")
    ...
    ...
    socket.onopen = function(e){
        form_data.submit(function(event){
            event.preventDefault()
            var form_entry = {
                "name": $("#id_name").val(),
                "number": $("#id_number").val(),
                "city": $("#id_city").val()
            }
            socket.send(JSON.stringify(form_entry))
            form_data[0].reset()
        })
    }

This form_entry data goes to my consumers.py, but since it is no longer a Django form object, I cannot use the .is_valid() method to validate the data (CharField max_length etc). I need to validate the data before I can process it in my consumers.py

The official documentation doesn't cover this because it uses the example of a chat app which doesn't require any such validation. In fact it doesn't even use Django forms.

I have 2 questions:

  1. Can I instantiate an EntryForm object in my consumers.py and then use the .is_valid() method on it there? How do I do this, since it is not an http request?

  2. If not, how else can I validate my form_entry data to make sure it obeys the model fields' conditions (DecimalField, CharField, max_length etc)?

Upvotes: 0

Views: 701

Answers (1)

oktested
oktested

Reputation: 81

This turned out to be easier than I thought. Didn't need DRF or any other framework.

In my consumer, I instantiated an object of my model (Entry) using the incoming data from the front-end, and then proceeded to perform the required operations on it. Django automatically checks if the data matches the criteria I've set in my model fields (CharField, max_length etc) and tells the user if there's an error! Quite impressed that this works even without forms. Saved me lots of work and time.

Upvotes: 0

Related Questions