在我的应用程序中,我有一个for循环,根据表单答案创建一个字典。它似乎被执行了两次,所以第一个dict(这是好的,我可以看到它)被第二个删除。我不明白为什么它被执行了两次!
我觉得问题来自模板相关(但我可能错了)。
这是模板:
{% extends "base.html" %}
{% block content %}
<h1>{{torrent.name}} is {{torrent.status}}</h1>
<form class="uk-form uk-form-row uk-form-horizontal" action="/torrent/{{torrent.hashString}}" method="post" name="torrent" >
{{control.hidden_tag()}}
<p>
<ul class="uk-breadcrumb">
<li><a href='/start/{{torrent.hashString}}'>Start</a></li>
<li><a href='/stop/{{torrent.hashString}}'>Stop</a></li>
</ul>
<button class="uk-button" name="button" id="button" type="submit" value="update">Update</button>
</p>
<div class="uk-grid">
<div class="uk-width-1-3 uk-panel uk-panel-header">
<h3 class="uk-panel-title">Status</h3>
<ul class="uk-list">
<li>Progress of download process : {{torrent.progress}} %</li>
<li>Priority : {{control.bandwidthpriority(default=torrent.bandwidthPriority)}}</li>
<li>Date of start : {{momentjs(torrent.addedDate).calendar()}}</li>
<li>Last start date : {{torrent.startDate}}</li>
{# <li>Estimated remaining time : {{torrent.eta}}</li>
<li>Leechers : {{torrent.leechers}}</li>
<li>Seeders : {{torrent.seeders}}</li> #}
</ul>
</div>
...
all kind of info but no controls
</div>
<p>Total size : {{torrent.totalSize|filesize}}</p>
{% if torrent.error != 0 %}
<p>There's a {{torrent.error}} :<br />
{{torrent.errorString}}</p>
{% endif %}
<h2>Files</h2>
<table class="uk-table">
<tr>
<th>File name</th>
<th>Completed / Size</th>
<th>Selected</th>
<th>Priority</th>
</tr>
{% for file in control.files %}
<tr>
{{file.key}}
<td>{{file.filename.data}}</td>
<td>{{file.completed.data}} / {{file.size.data}}</td>
<td>{{file.selected}}</td>
<td>{{file.priority}}</td>
{# <td><button type="submit">Send</button></td> #}
</tr>
{% endfor %}
</table>
</form>
{% endblock %}
这是视图:
@app.route('/torrent/<tor_id>', methods = ['GET','POST'])
@login_required
def torrent(tor_id):
user = g.user
# fetch informations about the torrent from transmission
torrent = client.get_torrent(tor_id)
# fetch information about the torrent from DB
tordb = Torrent.query.filter_by(hashstring = torrent.hashString).first()
if tordb.user != unicode(user):
return render_template("404.html")
else:
###
#error = ''
if torrent.error == 1:
torrent.error = 'tracker warning'
if torrent.error == 2:
torrent.error = 'tracker error'
if torrent.error == 3:
torrent.error = 'local error'
###
#if torrent.seedRatioMode == 0:
# torrent.seedRatioMode = 'Global ratio limit'
#if torrent.seedRatioMode == 1:
# torrent.seedRatioMode = 'Individual ratio limit'
#if torrent.seedRatioMode == 2:
# torrent.seedRatioMode = 'Unlimited seeding'
control = TorrentForm(bandwidthpriority=torrent.bandwidthPriority,ratiomode=torrent.seedRatioMode)
###
for file_x in client.get_files(tor_id)[torrent.id]:
f_form = TorrentFileDetails(csrf_enabled=False)
f_form.key = file_x
f_form.filename = unicode(client.get_files(tor_id)[torrent.id][file_x]['name'])
f_form.priority = client.get_files(tor_id)[torrent.id][file_x]['priority']
f_form.size = client.get_files(tor_id)[torrent.id][file_x]['size']
f_form.completed = client.get_files(tor_id)[torrent.id][file_x]['completed']
f_form.selected = client.get_files(tor_id)[torrent.id][file_x]['selected']
control.files.append_entry(f_form)
# the form is not validated because of the csrf trick !
if control.is_submitted():
update = False
# by default, ratio limit can be updated !
update_ratio_limit = True
if control.ratiomode.data != torrent.seedRatioMode:
if control.ratiomode.data == '0':
torrent.seed_ratio_mode = 'global'
# we don't allow anymore the ratio limit to be updated : the ratiolimit will be the gloabal one !
update_ratio_limit = False
if control.ratiomode.data == '1':
torrent.seed_ratio_mode = 'single'
if control.ratiomode.data == '2':
torrent.seed_ratio_mode = 'unlimited'
# we don't allow anymore the ratio limit to be updated : the ratiolimit will be the gloabal one !
update_ratio_limit = False
update = True
# if we are still allowed to update ratio limit
# eg : we haven't touched ratiomode in form - update_ratio_limit is still at its default : true
# or it has been changed to single mode
if update_ratio_limit:
if control.ratiolimit.data != torrent.seedRatioLimit:
torrent.seed_ratio_limit = float(control.ratiolimit.data)
torrent.seed_ratio_mode = 'single'
update = True
if control.downloadlimit.data != torrent.downloadLimit:
torrent.download_limit = int(control.downloadlimit.data)
update = True
if control.uploadlimit.data != torrent.uploadLimit:
torrent.upload_limit = int(control.uploadlimit.data)
update = True
if control.bandwidthpriority.data != torrent.bandwidthPriority:
if control.bandwidthpriority.data == '-1':
torrent.priority = 'low'
if control.bandwidthpriority.data == '1':
torrent.priority = 'high'
if control.bandwidthpriority.data == '0':
torrent.priority = 'normal'
update = True
# we use the ID returned by transmission itself ! Not the hashString.
# the first torrent.id is to say which torrent we are talking about. Transmission gives us a dict containing the info for the torrents asked.
# so the dict contains ONE torrent info
# but still, begin with the torrent.id, this is why the second torrent.id
files_answers = {}
for file_un in control.files: <<<< This is this loop which is executed two times !
# create a dict that contains the new priority for each file according to the form
file_answer = {}
if file_un.priority.data != client.get_files(tor_id)[torrent.id][int(file_un.key.data)]['priority']:
file_answer['priority'] = file_un.priority.data
if file_un.selected.data != client.get_files(tor_id)[torrent.id][int(file_un.key.data)]['selected']:
file_answer['selected'] = file_un.selected.data
# append the dict to the general dict previously created (files_answers).
# the key is the ID of the file itself ! >> no value name !
files_answers[int(file_un.key.data)] = file_answer
#finally, we create the last dict which will contain only one value : the files_answers dict !
answer = {}
answer[int(torrent.id)] = files_answers
update = True
client.set_files(answer)
if update:
torrent.update()
#start_stop_torrent(tor_id)
return render_template("torrent.html", title = torrent.name, user = user, torrent = torrent, control = control)
最后是表格:
# each individual file in the torrent have its own priority, thus, we need to manage them individually !
class TorrentFileDetails(Form):
key = HiddenField('key')
filename = HiddenField('filename')
size = HiddenField('size')
completed = HiddenField('completed')
selected = BooleanField('selected')
priority = SelectField(u'File priority',choices=[('low','low'),('normal','normal'),('high','high')])
# we desactivate the csrf cause this particular form is within the TorretForm, so it can't be several csrf at the same time !
def __init__(self, *args, **kwargs):
kwargs['csrf_enabled'] = False
super(TorrentFileDetails, self).__init__(*args, **kwargs)
class TorrentForm(Form):
hidden = HiddenField('hidden')
ratiolimit = DecimalField("ratio")
ratiomode = SelectField(u'Ratio mode', choices=[(0,'Global ratio limit'),(1,'Individual ratio limit'),(2,'Unlimited seeding')])
downloadlimit = DecimalField("down")
uploadlimit = DecimalField("up")
bandwidthpriority = SelectField(u'Torrent priority', choices=[( -1,'low'),(0,'normal'),(1,'high')])
# we append each individual file form to this, as we don't know how many there is in each torrent !
files = FieldList(FormField(TorrentFileDetails))
例如,这是iso torrent的html页面/表单。所以洪流中有一个文件!
<form class="uk-form uk-form-row uk-form-horizontal" action="/torrent/e3811b9539cacff680e418124272177c47477157" method="post" name="torrent" >
<div style="display:none;"><input id="csrf_token" name="csrf_token" type="hidden" value="20131212140726##1a06938d263188231da3de53ec343984b6b1e92b"><input id="csrf" name="csrf" type="hidden" value=""></div>
<p>
<ul class="uk-breadcrumb">
<li><a href='/start/e3811b9539cacff680e472177c47477157'>Start</a></li>
<li><a href='/stop/e3811b9539cacff680e472177c47477157'>Stop</a></li>
</ul>
<button class="uk-button" name="button" id="button" type="submit" value="update">Update</button>
</p>
<div class="uk-grid">
<div class="uk-width-1-3 uk-panel uk-panel-header">
<h3 class="uk-panel-title">Status</h3>
<ul class="uk-list">
<li>Total size : 0.9 GiB</li>
<li>Progress of download process : 100.0 %</li>
<li>Priority : <select id="bandwidthpriority" name="bandwidthpriority"><option value="-1">low</option><option selected value="0">normal</option><option value="1">high</option></select></li>
</ul>
</div>
<div class="uk-width-1-3 uk-panel uk-panel-header">
<h3 class="uk-panel-title">Downloading</h3>
<ul class="uk-list">
<li>Number of peers sending to us : 0</li>
<li>Download rate : 0 bits/s</li>
<li>Download limit : <input class="uk-form-width-small" id="downloadlimit" name="downloadlimit" type="number" value="100"> KB/s</li>
<li></li>
<li>Corrupt data downloaded : 0.0 KiB</li>
</ul>
</div>
<div class="uk-width-1-3 uk-panel uk-panel-header">
<h3 class="uk-panel-title">Uploading</h3>
<ul class="uk-list">
<li>Number of peers getting from us : 0</li>
<li>Upload rate : 0 bits/s</li>
<li><label class="uk-form-label" for="">Upload limit :</label><div class="uk-form-controls"><input class="uk-form-width-small" id="uploadlimit" name="uploadlimit" type="number" value="100"> KB/s</div></li>
<li></li>
<li><label class="uk-form-label" for="">Ratio mode :</label><div class="uk-form-controls"><select id="ratiomode" name="ratiomode"><option selected value="0">Global ratio limit</option><option value="1">Individual ratio limit</option><option value="2">Unlimited seeding</option></select></div></li>
<li><label class="uk-form-label" for="">Ratio limit :</label><div class="uk-form-controls"><input class="uk-form-width-small" id="ratiolimit" name="ratiolimit" step="0.1" type="number" value="2"></div></li>
<li>Ratio : 0.0</li>
</ul>
</div>
</div>
<h2>Files</h2>
<table class="uk-table">
<tr>
<th>File name</th>
<th>Completed / Size</th>
<th>Selected</th>
<th>Priority</th>
</tr>
<tr>
<input id="files-0-key" name="files-0-key" type="hidden" value="0">
<td>ubuntu-13.10-desktop-amd64.iso</td>
<td>835584 / 925892608</td>
<td><input checked id="files-0-selected" name="files-0-selected" type="checkbox" value="y"></td>
<td><select id="files-0-priority" name="files-0-priority"><option value="low">low</option><option selected value="normal">normal</option><option value="high">high</option></select></td>
</tr>
</table>
</form>
</div>
</body>
</html>
答案 0 :(得分:0)
循环不会这样做两次!
当点击按钮并执行validate_on_submit时,帖子包含双重答案:用户想要给出的答案以及原始数据!
在按下按钮之前:
[{'completed': 9705687, 'selected': True, 'filename': u'WADs/Doom WADs.7z', 'priority': u'normal', 'key': 0, 'size': 9705687},
{'completed': 4571349, 'selected': True, 'filename': u'WADs/Heretic WADs.7z', 'priority': u'normal', 'key': 1, 'size': 4571349},
{'completed': 7757653, 'selected': True, 'filename': u'WADs/Hexen WADs.7z', 'priority': u'normal', 'key': 2, 'size': 7757653}]
按下按钮后:
[{'completed': u'', 'selected': True, 'filename': u'', 'priority': u'normal', 'key': u'0', 'size': u''},
{'completed': u'', 'selected': True, 'filename': u'', 'priority': u'normal', 'key': u'1', 'size': u''},
{'completed': u'', 'selected': True, 'filename': u'', 'priority': u'normal', 'key': u'2', 'size': u''},
{'completed': 9705687, 'selected': True, 'filename': u'WADs/Doom WADs.7z', 'priority': u'normal', 'key': 0, 'size': 9705687},
{'completed': 4571349, 'selected': True, 'filename': u'WADs/Heretic WADs.7z', 'priority': u'normal', 'key': 1, 'size': 4571349},
{'completed': 7757653, 'selected': True, 'filename': u'WADs/Hexen WADs.7z', 'priority': u'normal', 'key': 2, 'size': 7757653}]
因此,经过处理的答案会经历好的一次,然后遍历原始数据,并擦除我们想要传递的好的值。