Django 消费者(Django 频道)中的表单数据验证(相当于 form.is_valid)

Posted

技术标签:

【中文标题】Django 消费者(Django 频道)中的表单数据验证(相当于 form.is_valid)【英文标题】:Form data validation (equivalent of form.is_valid) in a Django consumer (Django Channels) 【发布时间】:2019-09-19 19:12:11 【问题描述】:

我正在从基于 http 的设置(Django 表单、视图等)转移到使用 Django Channels 的 websocket 设置(原因不可避免)。在基于 http 的设置中,我在模板中使用表单(3 个字段 - 姓名、号码、城市)输入了一些数据:

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

由于此数据之前是作为 Django 表单提交的(使用“class Meta:”映射到我的 Django 模型),我可以轻松地在我的 views.py 中使用 form.is_valid() 方法对其进行验证.表单数据中的每个字段都具有某些条件,例如 CharField (max_length) 等,这些条件已通过我的 views.py 中的 is_valid() 方法进行验证:

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.')
...

正如您在上面看到的,表单属于我的 forms.py 中的一个表单类“EntryForm”,它映射到我的 models.py 中名为 Entry 的模型(其中包含名称、号码和城市等字段)。

但是在 Django Channels 中,为了提交表单数据,因为我必须使用脚本来 .preventDefault() 然后将数据作为单独的字典发送到我的 consumer.py,所以它没有到达那里作为 Django 表单。这是我的脚本:

<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()
        )
    

这个 form_entry 数据进入我的 consumer.py,但由于 它不再是 Django 表单对象,我不能使用 .is_valid() 方法 来验证数据(CharField max_length 等)。我需要先验证数据,然后才能在 consumer.py 中处理数据

官方文档没有涵盖这一点,因为它使用了不需要任何此类验证的聊天应用程序示例。事实上,它甚至不使用 Django 表单。

我有两个问题:

    我可以在我的 consumer.py 中实例化一个 EntryForm 对象,然后在那里使用 .is_valid() 方法吗?我该怎么做,因为它不是一个 http 请求?

    如果不是,我还能如何验证我的 form_entry 数据以确保它符合模型字段的条件(DecimalField、CharField、max_length 等)?

【问题讨论】:

由于您要发送 JSON,因此您应该使用 Django REST Framework 之类的东西,其中包括通过序列化程序进行验证。 【参考方案1】:

事实证明这比我想象的要容易。不需要 DRF 或任何其他框架。

在我的消费者中,我使用来自前端的传入数据实例化了我的模型(条目)的一个对象,然后继续对其执行所需的操作。 Django 会自动检查数据是否符合我在模型字段(CharField、max_length 等)中设置的标准,并告诉用户是否有错误!令人印象深刻的是,即使没有表格也可以使用。为我节省了大量的工作和时间。

【讨论】:

以上是关于Django 消费者(Django 频道)中的表单数据验证(相当于 form.is_valid)的主要内容,如果未能解决你的问题,请参考以下文章

Django 频道中的消费者

如何在 django 频道中从消费者类外部发送普通 JSON 消息

我如何订阅消费者并通知他 Django 频道的任何变化

在 Django 频道上找不到路径

Django 频道实时聊天保存发送的消息

Django 频道 - websocket_disconnect 在循环中被调用