Django:如何通过单击一行来更改页面?

Posted

技术标签:

【中文标题】Django:如何通过单击一行来更改页面?【英文标题】:Django: How to change the page at the click of a line? 【发布时间】:2015-08-11 01:26:21 【问题描述】:

当我单击 html 中标签中的一行时,我试图在 Ddjango 中创建一些视图,我需要一些建议,请考虑到我是 Django 的初学者。 事实上,当我点击它时,我想改变我的视图,什么会打开一个新视图,就像我的标签内的Hash。 让我用这个名为bap2pmonitoring.html的代码来解释你:

% load staticfiles %
<!DOCTYPE html>
<html lang="fr">
<head>
    <link rel="stylesheet" type="text/css" href="% static 'css/style.css' %" />
</head>
<body>

<h1> BAP2P Monitoring</h1>


<table>
    <tr>
        <th width=550 height=20>Torrent Hash</th>
        <th width=720 height=20>Torrent Name</th>
        <th width=120 height=20>Size</th>
        <th width=170 height=20>Active Peers</th>
    </tr>

% for torrent in torrents %
        <p id="demo">
        <tr bgcolor=eeeeee> 
            <td width=550 height=20><a href=" url 'hash' torrent.Hash "> torrent.Hash </a></td>
            <td width=720 height=20> torrent.Name </td>
            <td width=120 height=20> torrent.Size </td>
            <td width=170 height=20></td>
    </tr>
        </p>
% endfor %

</table>

</body>
</html>

我因此得到这个结果:

![在此处输入图片描述][1]

我的想法是,当我点击这两行之一时,它会呈现一个新视图,其中包含有关此种子的信息,其中种子的哈希为 url,如下所示:

127.0.0.1:8000/torrents/606d4759c464c8fd0d4a5d8fc7a223ed70d31d7b

按照 Django 教程,我尝试了很多事情都没有成功,然后我尝试了一个“onclick”在我的 view.py 中启动我的 def 之一,如下所示:

from django.shortcuts import render_to_response
from django.template import Template , Context
from polls.models import Torrent
# Create your views here.
# -*- coding: utf-8 -*-

def home(request):  
    return render_to_response('mysite/bap2pmonitoring.html', 'torrents':Torrent.objects.all())


def details(request, torrent_hash):
    return render_to_response('mysite/detail_torrent.html', 'torrents':Torrent.objects.filter(hash=torrent_hash))

我还尝试在urls.py 中将哈希显示为这样的网址:

from django.conf.urls import patterns,include, url
from django.contrib import admin
from polls.models import Torrent

urlpatterns = patterns('polls.views',

     url(r'^torrents$', 'home', name = 'home'),
     url(r'^torrents/(?P<torrent_hash>)/$', 'details', name = 'hash'),
     url(r'^admin/', include(admin.site.urls)),
)

我不明白我该如何解决这个问题,欢迎和赞赏任何想法

现在我得到这个错误页面:

NoReverseMatch at /torrents

Reverse for 'hash' with arguments '(u'606d4759c464c8fd0d4a5d8fc7a223ed70d31d7b',)' and keyword arguments '' not found. 1 pattern(s) tried: ['torrents/(?P<torrent_hash>)/$']

还有这个 Traceback:

   Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/torrents

Django Version: 1.8.1
Python Version: 2.7.3
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'polls')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')


Template error:
In template /home/florian/Documents/mysite/templates/mysite/bap2pmonitoring.html, error at line 23
   Reverse for 'hash' with arguments '(u'606d4759c464c8fd0d4a5d8fc7a223ed70d31d7b',)' and keyword arguments '' not found. 1 pattern(s) tried: ['torrents/(?P<torrent_hash>)/$']

   13 :     <tr>



   14 :         <th width=550 height=20>Torrent Hash</th>



   15 :         <th width=720 height=20>Torrent Name</th>



   16 :         <th width=120 height=20>Size</th>



   17 :         <th width=170 height=20>Active Peers</th>



   18 :     </tr>



   19 : 



   20 : % for torrent in torrents %



   21 :         <p id="demo">



   22 :         <tr bgcolor=eeeeee> 



   23 :             <td width=550 height=20><a href=" % url 'hash' torrent.Hash % "> torrent.Hash </a></td>



   24 :             <td width=720 height=20> torrent.Name </td>



   25 :             <td width=120 height=20> torrent.Size </td>



   26 :             <td width=170 height=20></td>



   27 :         </tr>



   28 :         </p>



   29 : % endfor %



   30 : 



   31 : </table>



   32 : 



   33 : </body>


Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/florian/Documents/mysite/polls/views.py" in home
  8.     return render_to_response('mysite/bap2pmonitoring.html', 'torrents':Torrent.objects.all())
File "/usr/local/lib/python2.7/dist-packages/django/shortcuts.py" in render_to_response
  39.         content = loader.render_to_string(template_name, context, using=using)
File "/usr/local/lib/python2.7/dist-packages/django/template/loader.py" in render_to_string
  99.         return template.render(context, request)
File "/usr/local/lib/python2.7/dist-packages/django/template/backends/django.py" in render
  74.         return self.template.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  209.                     return self._render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in _render
  201.         return self.nodelist.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  903.                 bit = self.render_node(node, context)
File "/usr/local/lib/python2.7/dist-packages/django/template/debug.py" in render_node
  79.             return node.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py" in render
  217.                             nodelist.append(node.render(context))
File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py" in render
  507.                         six.reraise(*exc_info)
File "/usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py" in render
  493.             url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in reverse
  579.     return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in _reverse_with_prefix
  496.                              (lookup_view_s, args, kwargs, len(patterns), patterns))

Exception Type: NoReverseMatch at /torrents
Exception Value: Reverse for 'hash' with arguments '(u'606d4759c464c8fd0d4a5d8fc7a223ed70d31d7b',)' and keyword arguments '' not found. 1 pattern(s) tried: ['torrents/(?P<torrent_hash>)/$']

【问题讨论】:

我相当肯定写一些 javascript/jQuery 是你的未来。 目前您正在将 Torrent.objects.all() 作为上下文传递到您的详细信息视图中。您需要访问单个 torrent,而不是全部,例如 Torrent.objects.filter(torrent.Hash=Hash),具体取决于您作为 PK 的内容 【参考方案1】:

您需要:

更改您的详细视图的上下文以仅访问单个种子,并且还包括来自 URL 的参数:

details(request, torrent_hash):
    return render_to_response('mysite/detail_torrent.html', 'torrent':Torrent.objects.filter(hash=torrent_hash))

使用这样的 URL,它将通过您的种子哈希传递到视图:

 url(r'^torrents/(?P<torrent_hash>)/$', 'details', name = 'hash'),

您还需要您的 detail_torrent.html 模板,然后您可以在其中使用您的“torrent”上下文。

编辑以抢占另一个问题:

在您的主模板中,您可以使用此更改链接到 torrent。然后,您将 torrent.Hash 变量作为参数传递给您的 URL,该参数将用于 URL 正则表达式中的 torrent_hash:

% for torrent in torrents %
    <p id="demo">
    <tr bgcolor=eeeeee> 
        <td width=560 height=20><a href="% url 'hash' torrent.Hash %"> torrent.Hash </a></td>
        <td width=710 height=20> torrent.Name </td>
        <td width=110 height=20> torrent.Size </td>
        <td width=110 height=20></td>
    </tr>
    </p>
% endfor %

【讨论】:

我编辑了您的更改,并在 Traceback 中添加了一个错误,原因是 HTML 显然存在问题 您的 urls.py 是否与 url(r'^torrents/(?P&lt;torrent_hash&gt;)/$', 'details', name = 'hash') 匹配? 我的错误,您需要在链接周围使用百分比符号 % url 'hash' torrent.Hash % 而不是 url 'hash' torrent.Hash @OliverM : 我再次编辑它不一样的 Traceback 我不明白 您需要根据您的哈希值将正确的正则表达式添加到 URL 中。类似 (?P[\w]+)【参考方案2】:

onlick 属性不会调用您的服务器端视图函数。它是一个 JavaScript 偶数处理程序,因此它将寻找一个名为 details() 的 JS 函数,因为它看起来不像你有一个它不会做任何事情。您可以通过打开浏览器开发工具并转到“控制台”选项卡来确认这一点。一旦你在那里点击你的行,你会看到看起来像这样的东西:

Uncaught ReferenceError: details is not defined

您需要编写一个 JS 函数,该函数将返回到您的服务器,以便您的服务器可以发送一个新页面进行渲染。我强烈推荐使用 jQuery,因为它会让你的生活变得更简单。

首先你需要修改你的 HTML,因为有一些错误:

% for torrent in torrents %
    <tr class="torrent" id=" torrent.Hash " > 
      <td width=550 height=20> torrent.Hash </td>
      <td width=720 height=20> torrent.Name </td>
      <td width=120 height=20> torrent.Size </td>
      <td width=170 height=20></td>
    </tr>
% endfor %

id HTML 元素的属性应该是唯一的,我们稍后将在 JS 中使用它来获取正确的 URL。无需将&lt;tr&gt; 包装在&lt;p&gt; 标记中,所以让我们摆脱它。我在编写 JS 时添加了一个类,让我们的生活更轻松。

现在是 JS:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
  $(".torrent").on('click', function()
    var hash = $(this).attr('id');
    window.location.href = '/torrents/' + hash;
  );
</script>

请务必将其包含在模板中的结束 &lt;body&gt; 标记上方。

或者,您不能添加 CSS 类并使用此 jQuery 选择器$('tr'),但仅当这是页面上唯一的表时才这样做。

这将为您创建一个 URL,然后在您单击表格行的任意位置时打开该 URL。

urlpatterns = patterns('polls.views',
     url(r'^torrents$', 'home', name = 'home'),
     url(r'^torrents/(?P<torrent_hash>)/$', 'details', name='hash'),  # this line
     url(r'^admin/', include(admin.site.urls)),
)

您需要调整我指出的线路,使其正常工作。最后修改您的视图以接受您的新参数:

def details(request, torrent_hash):
    return render_to_response('mysite/detail_torrent.html', 'torrents':Torrent.objects.get(Hash=torrent_hash))

编辑:再迈一步,让用户清楚他们可以点击表格行以转到您希望在 CSS 中使用的新网址:

.torrent:hover 
  cursor: pointer;

【讨论】:

非常好的答案,非常感谢。除了 Javascript,我得到了它,因为我不知道 Javascript,但它可以工作,除了我不继续使用 mysite/detail_torrent.html 而是使用 Page not found (404) ^^ 您是否创建了一个名为detail_torrent.html的模板文件? 是的,我在与bap2pmonitoring.html相同的位置完成了 这个问题有点超出这个问题的范围。您应该使用此问题的详细信息打开一个新问题。【参考方案3】:

多亏了拉尔夫的建议,我成功地做到了和发帖人一样的事情。但是,通过一项调整,即我(有意)停留在初始页面上,即在上面的示例中,我仅使用

'mysite/bap2pmonitoring.html'

我调用的地方

<a href=" url 'hash' torrent.Hash "> torrent.Hash </a> 

(在 for 循环内)

视图因此指向“mysite/bap2pmonitoring.html”而不是“mysite/detail_torrent.html”

就链接而言,一切都很好。但是,一旦我单击链接并显示详细信息视图的结果(正确),循环的链接就会消失。初始页面的其他所有内容都保留下来。有没有办法防止这种情况发生,即保留链接?

(想法是创建一个面板并在下面显示详细信息,可以通过面板的链接更新详细信息)

【讨论】:

请不要使用答案来提问。考虑制定一个单独的问题。

以上是关于Django:如何通过单击一行来更改页面?的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中,如何单击按钮来调用视图然后重新加载页面

如何通过按钮更改 Django 模板使用的 CSS?

通过鼠标单击选项卡来捕获选项卡更改事件

不允许单击元素的边距来更改页面

如何通过单击导航栏导航到其他页面

从 django 管理操作中间页面重定向到更改表单页面