【问题标题】:Save Changes to Database using Django and x-editable使用 Django 和 x-editable 将更改保存到数据库
【发布时间】:2015-08-06 10:04:35
【问题描述】:

我是 JS、HTML、Django 和所有相关内容的新手,我无法通过阅读文档或使用 Google 自行解决问题。

我想在 django 环境中使用 x-editable 将内联更改保存到数据库中。下面的模板完美运行,但现在我想用新名称覆盖数据库条目。

我试图将代码简化为我的问题的相关部分。

models.py:

class MyClass(models.Model):
      name = models.CharField(max_length=120)

views.py:

def list(request):
    return render(request, 'list.html', {'list':MyClass.objects.all()}

urls.py:

url(r'^list/$', 'myapp.views.list', name='list'),

list.html:

{% extends "base.html" %}
{% block content %}
<script>
    $(document).ready(function() {
        $.fn.editable.defaults.mode = 'inline';   
        $('.name').editable({

        });
    });
</script>

<h1>Names</h1>
   <div>
        <table border='1'>
            {% for l in list %}
            <tr><td><a class="name">{{ l.name }}</a></td></tr>
            {% endfor %}
        </table>
    </div>

{% endblock %}

----------------------------------------------- ---------

我最有希望的方法是创建一个更新视图。

def list_update(request, pk):
    l = get_object_or_404(MyClass, pk=pk)
    form = ListForm(request.POST or None, instance=l)
    if form.is_valid():
        form.save()
        return redirect('list')
    return render(request, '', {'form':form})

并将以下几行添加到上面的代码中:

urls.py
    url(r'^update/(?P<pk>\d+)$', 'myapp.views.list_update', name='list_update'),


list.html
    $('.name').editable({
        pk: l.pk,
        url: '{% url 'list_update' l.pk%}',
    });

但是这种尝试会导致 NoReverseMatch 错误,并且 l.pk 似乎是空的。我感谢任何有关如何以正确方式执行此操作的帮助。

【问题讨论】:

  • 我遇到了类似的问题,你有没有机会更新我们,让我们知道你是否设法解决了问题?

标签: django x-editable


【解决方案1】:

urls.py:

    url(r'^xed_post$', views.xed_post, name='xed_post'),

views.py 中的 Django 视图代码(基于函数):

from django.http import JsonResponse

def xed_post(request):
    """
    X-Editable: handle post request to change the value of an attribute of an object

    request.POST['model']: name of Django model of which an object will be changed
    request.POST['pk']: pk of object to be changed
    request.POST['name']: name of the field to be set
    request.POST['value']: new value to be set
    """
    try:
        if not 'name' in request.POST or not 'pk' in request.POST or not 'value' in request.POST:
           _data = {'success': False, 'error_msg': 'Error, missing POST parameter'}
          return JsonResponse(_data)

        _model = apps.get_model('swingit', request.POST['model'])  # Grab the Django model
        _obj = _model.objects.filter(pk=request.POST['pk']).first()  # Get the object to be changed
        setattr(_obj, request.POST['name'], request.POST['value'])  # Actually change the attribute to the new value
        _obj.save()  # And save to DB

        _data = {'success': True}
        return JsonResponse(_data)

    # Catch issues like object does not exist (wrong pk) or other
    except Exception as e:
        _data = {'success': False,
                'error_msg': f'Exception: {e}'}
        return JsonResponse(_data)

然后,在 list.html 中:

{% extends "base.html" %}
{% block content %}
<script>
    $(document).ready(function() {
        $.fn.editable.defaults.mode = 'inline';   
        $('.name').editable({
            params: {
                csrfmiddlewaretoken:'{{csrf_token}}',
                model:'MyClass'
            },
            url: '/xed_post',
            error: function(response, newValue) {
                return response.responseText;
            },
            success: function(response, newValue) {
                if(!response.success) return response.error_msg;
            }
        });
    });
</script>

<h1>Names</h1>
   <div>
        <table border='1'>
            {% for l in list %}
            <tr><td><a class="name" data-name="name" data-type="text" data-pk="{{ l.pk }}">{{ l.name }}</a></td></tr>
            {% endfor %}
        </table>
    </div>

{% endblock %}

请注意,对 css 类和 Django 字段名称都使用“名称”会造成混淆。 data-name="name" 指的是 Django 字段名,而 class="name" 指的是 css 类。

【讨论】:

  • 谢谢。这是天才。点赞!现在就用它编码......
  • 有 CSRF 问题。不适用于我的设置,尝试了一百万件事,阅读 Django 文章。有什么指导吗?
【解决方案2】:

Davy 的代码不能按原样工作(对我而言)。

但是如果你添加:

$.ajaxSetup({
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});     

在一切之前,只要您在 html 模板中的某处有 {% csrf_token %}。我只是把它放在顶部,因为我使用的是 X-editable 并且模板中没有表单标签。

所以在某处添加 {% csrf_token %} 行并将 Davy 的 JS 代码更改为:

{% extends "base.html" %}
{% block content %}
<script>
    $.ajaxSetup({
        data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
    });             

    $(document).ready(function() {
        $.fn.editable.defaults.mode = 'inline';   
        $('.name').editable({
            params: {
                model:'MyClass'
            },
            url: '/xed_post',
            error: function(response, newValue) {
                return response.responseText;
            },
            success: function(response, newValue) {
                if(!response.success) return response.error_msg;
            }
        });
    });
</script>

它应该可以工作。请注意,我从 params 字典中删除了 {{ csrf_token }} 行,因为 AJAX 设置调用会处理它,所以它不是必需的(至少对于我的设置而言)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 2020-03-29
    • 2021-02-15
    • 2013-02-28
    • 2014-04-21
    • 1970-01-01
    • 2012-07-07
    相关资源
    最近更新 更多