You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过HTML表单创建Person实例并保存至AuraDB?

问题描述

多数在线教程都是讲解如何用Django将模型实例保存到本地数据库,我尝试实现将数据存入Neo4j(AuraDB连接正常),但运行项目后访问http://127.0.0.1:8000/person出现异常。我希望通过用户表单输入创建Person实例并保存到AuraDB,当前实现存在问题,相关代码如下:

Person模型(models/person.py)

from neomodel import StructuredNode, StringProperty, IntegerProperty,UniqueIdProperty, RelationshipTo
from myapi.models.city import City


class Person(StructuredNode):
    uid = UniqueIdProperty()
    name = StringProperty(unique_index=False)
    age = IntegerProperty(index=True, default=0)
    email = StringProperty(unique_index=True)

    # Relations :
    city = RelationshipTo(City, 'LIVES_IN')
    friends = RelationshipTo('Person','FRIEND')

    def __unicode__(self):
        return self.uid

表单定义(views/forms.py)

from django import forms
from splitjson.widgets import SplitJSONWidget
from myapi.models import Person


class testForm(forms.Form):
    attrs = {'class': 'special', 'size': '40'}
    data = forms.CharField(widget=SplitJSONWidget(attrs=attrs, debug=True))
    class Meta:
        model = Person

URL配置(urls.py)

from django.urls import re_path as url
from myapi.views import *
from django.urls import path
urlpatterns = [
    path('', home, name='home'),
    path('home', home, name='home'),
    path('sign-up', sign_up, name='sign_up'),
    path('test-dict', test_dict, name='test_dict'),
    path('person',personDetails),
    path('getAllPersons',getAllPersons),
    path('city',cityDetails),
    path('getAllCities',getAllCities),
    path('connectPaC',connectPaC),
    path('connectPaP',connectPaP)
]

视图函数(home.py中的test_dict)

from django.template import RequestContext
from .forms import testForm
from django.template.loader import render_to_string

def test_dict(request):
    json = {'name': 1,
            'age': 4}
    form = testForm(request.POST or None, initial={'data': json})
    if form.is_valid():
        # validate and save
        pass

    template = 'myapi/test_template.html'
    #context = RequestContext(request, render_to_string(form))
    return render(request, template, {'form': form})

Person相关视图(views/persons.py)

from django.http import JsonResponse
from myapi.models import Person
from django.views.decorators.csrf import csrf_exempt
import json
from django.shortcuts import render, redirect


def getAllPersons(request):
    if request.method == 'GET':
        try:
            persons = Person.nodes.all()
            response = []
            for person in persons :
                obj = {
                    "uid": person.uid,
                    "name": person.name,
                    "age": person.age,
                }
                response.append(obj)
            return JsonResponse(response, safe=False)
        except:
            response = {"error": "Error occurred"}
            return JsonResponse(response, safe=False)
@csrf_exempt
def personDetails(request):
    if request.method == 'GET':
        # get one person by name
        name = request.GET.get('name', ' ')
        try:
            person = Person.nodes.get(name=name)
            response = {
                "uid": person.uid,
                "name": person.name,
                "age": person.age,
            }
            return JsonResponse(response, safe=False)
        except :
            response = {"error":"Error occurred"}
            return JsonResponse(response, safe=False)
            #return render(response, 'myapi/test_template.html')

    if request.method == 'POST':
        # create one person
        json_data = json.loads(request.body)
        name = json_data['first_name']
        email = str(json_data['email'])
        try:
            person = Person(name=name, email=email)
            person.save()
            response = {
                "uid": person.uid,
            }
            return JsonResponse(response)
        except :
            response = {"error":"Error occurred"}
            return JsonResponse(response, safe=False)

    if request.method == 'PUT':
        # update one person
        json_data = json.loads(request.body)
        name = json_data['name']
        age = int(json_data['age'])
        uid = json_data['uid']
        try:
            person = Person.nodes.get(uid=uid)
            person.name = name
            person.age = age
            person.save()
            response = {
                "uid": person.uid,
                "name": person.name,
                "age": person.age,
            }
            return JsonResponse(response, safe=False)
        except:
            response = {"error":"Error occurred"}
            return JsonResponse(response, safe=False)

    if request.method == 'DELETE':
        # delete one person
        json_data = json.loads(request.body)
        uid = json_data['uid']
        try:
            person = Person.nodes.get(uid=uid)
            person.delete()
            response = {"success": "Person deleted"}
            return JsonResponse(response, safe=False)
        except:
            response = {"error":"Error occurred"}
            return JsonResponse(response, safe=False)

修复步骤

1. 修正表单定义

当前用的forms.Form是普通表单,无法直接关联Person模型,改用forms.ModelForm直接映射模型字段,无需复杂的JSON组件:

from django import forms
from myapi.models import Person

class PersonForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = ['name', 'age', 'email']  # 直接指定需要用户输入的字段

2. 调整test_dict视图,处理表单提交逻辑

原视图未实现保存逻辑,修改后直接从表单提取数据创建Person实例并保存:

from django.shortcuts import render
from .forms import PersonForm
from myapi.models import Person

def test_dict(request):
    form = PersonForm(request.POST or None)
    if request.method == 'POST' and form.is_valid():
        # 从表单获取清洗后的数据
        person_data = form.cleaned_data
        # 创建Person实例并保存到AuraDB
        person = Person(**person_data)
        person.save()
    
    template = 'myapi/test_template.html'
    return render(request, template, {'form': form})

3. 修复personDetails视图的POST逻辑

原POST方法处理的是JSON请求,表单提交是application/x-www-form-urlencoded格式,需改用request.POST.get()获取数据,同时修正字段名(模型中是name而非first_name):

@csrf_exempt
def personDetails(request):
    # ... 保留其他请求方法逻辑 ...
    if request.method == 'POST':
        # 处理表单提交或普通POST请求
        name = request.POST.get('name')
        email = request.POST.get('email')
        age = request.POST.get('age', 0)  # 设置默认值避免空值报错
        try:
            person = Person(name=name, email=email, age=int(age))
            person.save()
            response = {"uid": person.uid}
            return JsonResponse(response)
        except Exception as e:
            # 打印错误用于调试,上线后可移除
            print(str(e))
            response = {"error": str(e)}
            return JsonResponse(response, safe=False)
    # ... 保留其他请求方法逻辑 ...

4. 调整模板渲染(test_template.html)

确保模板正确渲染表单,添加CSRF令牌:

<form method="POST" action="{% url 'test_dict' %}">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">提交</button>
</form>

5. 调试建议

  • 提交表单后查看控制台输出,可快速定位具体错误
  • 确认settings.py中Neo4j的连接配置正确
  • 原/person的GET请求需要传name参数(如/person?name=xxx),可修改逻辑支持不传参数时返回所有数据(与getAllPersons合并)

内容的提问来源于stack exchange,提问作者Ranjan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:27:06