Let me start with a more simple image list to act as a cleaner example:
images = [
(1, u'True', u'file_one.jpg', u'2013'),
(2, u'False', u'file_two.jpg', u'2012'),
]
You then refine that list of tuples to be choices to use for the form values, essentially the goal is to provide a list of two value tuples to wtforms:
[
(1,'file_one.jpg'),
(2,'file_two.jpg')
]
But you use this list comprehension:
rows = [(str(x[0]), x) for x in images]
form.images.choices = rows
Which will generate:
[
(1, (1, u'True', u'file_one.jpg', u'2013')),
(2, (2, u'False', u'file_two.jpg', u'2012'))
]
Which isn't useful to wtforms, it doesn't know how to handle that tuple within a tuple. So you need to pick the value for the label, or format that data better.
So either alter your list comprehension to pick a better description, which will get you to the goal:
rows = [(x[0],x[2]) for x in images]
Or join all the data together to give a more.. verbose but potentially useful to you description:
rows = [(x[0], "\t|".join([str(y) for y in x])) for x in images]
Which will result in:
[
(1, '1\t|True\t|file_one.jpg\t|2013'),
(2, '2\t|False\t|file_two.jpg\t|2012')
]
Read up more on list comprehensions.