【问题标题】:No Project matches the given query没有项目与给定的查询匹配
【发布时间】:2015-03-25 03:06:06
【问题描述】:

首先,我当然知道我确实有一个与给定查询匹配的项目,所以我不明白这个错误。开始了。

我的 urls.py 中有这两种模式,一种用于创建,另一种用于编辑:

urlpatterns = patterns('',
    url(r'^(?P<project_id>[A-Z0-9_a-z]+)/add_test_setup/$', add_test_setup, name="add_test_setup"),
    url(r'^(?P<project_id>[0-9]+)/testSetup/(?P<testsetup_id>\w+)/edit/$', add_test_setup, name="edit_test_setup"),
)

这是等效的视图:

def add_test_setup(request, project_id, testsetup_id=None):

    project = get_object_or_404(Project, pk=int(project_id))

    if testsetup_id != None:
        testsetup = get_object_or_404(TestSetup, pk=int(testsetup_id))
        testsetupform = TestSetupForm(request.POST or None, instance=testsetup)

        if request.method == "POST" and testsetupform.is_valid():
            testsetupform.save()
            return redirect("/projects/"+testsetup.project.ref+"/info/#tabr2", testsetup.project.ref)

        else:
            return render_to_response('projects/edit_test_setup.html', {'testsetupform':testsetupform,'project':project}, context_instance=RequestContext(request))

    else:
        testsetupform = TestSetupForm(request.POST or None)

        if request.method == "POST" and testsetupform.is_valid():
            testSetup.save()
            return redirect("/projects/"+project.ref+"/info/#tabr2", project.ref)

        else:
            return render_to_response('projects/add_test_setup.html', {'testsetupform':testsetupform,'project':project}, context_instance=RequestContext(request))

这些是模型:

class Project(models.Model):

    STATUS_CHOICES = ((0,'Not started'),(1,'ZERO'),(2,'KOM'))

    ref         = models.CharField(max_length=70, unique=True)
    description = models.TextField(_("Description"),max_length=170, blank=True)
    notes       = models.TextField(max_length=170,blank=True)
    customer    = models.CharField(max_length=70)
    operator    = models.ManyToManyField(User)
    supervisor  = models.CharField(max_length=70, blank=True)
    start_date  = models.DateField(blank=True,null=True)
    finish_date = models.DateTimeField(blank=True, null=True)
    status      = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_CHOICES[0][1])
    goal        = models.TextField(max_length=170, blank=True)


class TestSetup(models.Model):

    ref         = models.CharField(max_length=30)
    description = models.TextField(max_length=200,null=True,blank=True)
    notes       = models.TextField(max_length=200,null=True,blank=True)
    project     = models.ForeignKey(Project)

    def __unicode__(self):
        return "Test set-up %s" % (self.ref)

添加新的 TestSetup 没有任何问题,但是当我编辑 TestSetup 时,它会抛出 404“No Project matches the given query”。一开始我以为是视图的get_object_or_404有问题,后来我把这段代码注释掉,换成Project.objects.get(id=int(project_id))。没啥事儿。

这是我执行 testsetupform 版本的 HTML 代码部分:

<form class="vertical" method="post" action="{% url 'edit_test_setup' testsetupform.instance.project.id testsetupform.instance.id %}"> {% csrf_token %}

    {{testsetupform}}

    <h6 style="margin-top:30px">Assign series <span class="tooltip" title="Assign series to this test set-up."><i class="fa fa-question-circle" style="cursor:pointer;color:green;"></i></span></h6>
    <hr class="alt1" />

    <input type="submit" class="button blue" value="Save" style="margin-top:30px"></input>
</form>

另外,在 404 页面中,会出现:

Request Method:     POST
Request URL:    http://127.0.0.1:8000/projects/5/testSetup/16/edit/

因此,Project(id=5) 和 TestSetup(id=16) 模型都存在!我已经用其他项目模型进行了测试并抛出了同样的错误。

----------- EDITION.1 ------------

另外,使用./manage.py shell:

>>> from django.shortcuts import get_object_or_404
>>> from projects.models import Project
>>>
>>> project = get_object_or_404(Project, pk=5)
>>> project
<Project: 182TRE>
>>> Project.objects.get(id=5)
<Project: 182TRE>
>>> 

----------- END OF EDITION.1 ------------

问题可能出在哪里?

----------- EDITION.2 ------------

我在 HTML 表单中使用render_to_string 快捷方式。当我编辑 TestSetup 时会调用此快捷方式。我拥有的是一个带有 DIV 的主体模板,我在其中加载了一个附加模板来编辑这些 TestSetups。这是我用来请求此模板的 AJAX 调用:

function loadTestSetup(setup_id){

    $.ajax({
         type: "GET",
         url : '/projects/testSetup/'+ setup_id + '/load/',
         data: "",
         dataType: 'text',
         success : function (data, textStatus, request) {
             data = eval("(" + data + ")");
             $("#testsetupedit-dialog").html(data.html)  // "testsetupedit-dialog" is a div of the original template.
         }
    });

}

此 AJAX 调用通过此视图请求模板:

def load_test_setup(request, setup_id):

    testSetup = get_object_or_404(TestSetup, pk=int(setup_id))
    setupform = TestSetupForm(None, instance=testSetup)

    data = {'html':""}

    data['html'] = render_to_string('projects/test_setup_form.html', {'setupform':setupform}, context_instance=RequestContext(request))

    return HttpResponse(simplejson.dumps(data))

使用此网址模式:

url(r'^testSetup/(?P<setup_id>\w+)/load/$', load_test_setup, name="load_test_setup"),

我会不会对render_to_string 使用不当?

----------- END OF EDITION.2 ------------

【问题讨论】:

  • 当您将get_object_or_404 替换为Project.objects.get(id=int(project_id)) 时,您是否收到ObjectDoesNotExist 异常?
  • 没什么。同样的404错误,没有ObjectDoesNotExist异常。

标签: django django-forms http-status-code-404


【解决方案1】:

重定向后您收到 404 错误。 这一行:

return redirect("/projects/"+testsetup.project.ref+"/info/#tabr2", testsetup.project.ref)

或者这一行:

return redirect("/projects/"+project.ref+"/info/#tabr2", project.ref)

将您重定向到错误的 URL,您会得到 404。

建议:

  1. 检查此行中生成了哪些 URL,确保它们已在您的项目中注册。
  2. (更好)使用django.core.urlresolvers.reverse 生成用于重定向的URL。如果 URL 未注册,它将引发更有意义的异常。

【讨论】:

  • 这不是错误,因为我已经在其他视图中成功使用了这些行。我正在编辑问题,添加一些可能很重要的新信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
  • 1970-01-01
  • 2021-05-07
  • 2019-07-21
  • 2021-11-21
  • 2016-12-05
  • 2022-10-05
相关资源
最近更新 更多