jinja2 nested for loops two lists

|▌冷眼眸甩不掉的悲伤 提交于 2020-08-09 18:41:50

问题


I have the following code that is not rendering the way I would like on the html front end.

{% for image in images %}
    {% for title in titles %}
        <div class="card" style="width: 18rem;">
          <img src="{{image}}" class="card-img-top" alt="...">
          <div class="card-body">
        
            <h5 class="card-title">{{title}}</h5>
            <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
            <a href="#" class="btn btn-primary">Go somewhere</a>

            
</div>
    {% endfor %}
{% endfor %}

Essentially, images and titles are both lists of URLS. The images works correctly when on it's own to redner the HTML with all the images.

However, when I try to add titles, which is basically the image URL sliced to give only part of the URL text, in the above format, it messes up the formatting, displaying only one image.

I have tried various different ways but it doesn't work.

I want the code to display all the images in the cards, and in the TITLE field, display the corresponding title, and title in this case is the sliced string (or so I think)

The python (Flask) route, function that scrapes the images URLS and slicing code is shown here:

@app.route('/') #this is what we type into our browser to go to pages. we create these using routes
@app.route('/home')
def home():
    images=imagescrape()
    titles=(images[58:])
    #gettitles=gettitle()
    #titles=(gettitles[58:93])
    return render_template('home.html',images=images,titles=titles)


def imagescrape():
    result_images=[]
    #html = urlopen('https://en.wikipedia.org/wiki/Prince_Harry,_Duke_of_Sussex')
    html = urlopen('https://en.wikipedia.org/wiki/Rembrandt')
    bs = BeautifulSoup(html, 'html.parser')
    images = bs.find_all('img', {'src':re.compile('.jpg')})
    for image in images:
        result_images.append("https:"+image['src']+'\n') #concatenation!
    return result_images

UPDATE:

I've got this which NEARLY Works but not quite. It displays an image, then ALL the image urls text, instead of the corresponding one.

{% for image in images %}

        <div class="card" style="width: 18rem;">
          <img src="{{image}}" class="card-img-top" alt="...">
          <div class="card-body">
            {% for title in titles %}
            <h5 class="card-title">{{title}}</h5>
            {% endfor %}
            <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
            <a href="#" class="btn btn-primary">Go somewhere</a>

            
          </div>
        </div>
{% endfor %}

I think only a small change is needed for it to work but I don't know what.


回答1:


Combine the two lists of images and titles one by one.
For the iteration, unpack the two variables of the respective tuple.

import re                          # regular expressions used to match strings 
from bs4 import BeautifulSoup      # web scraping library
from urllib.request import urlopen # open a url connection 
from urllib.parse import unquote   # decode special url characters

@app.route('/')
@app.route('/home')
def home():
    images=imagescrape()
    # Iterate over all sources and extract the title from the URL
    titles=(titleextract(src) for src in images)
    
    # zip combines two lists into one.
    # It goes through all elements and takes one element from the first
    # and one element from the second list, combines them into a tuple 
    # and adds them to a sequence / generator.
    images_titles = zip(images, titles)
    return render_template('home.html', image_titles=images_titles)

def imagescrape():
    result_images=[]
    #html = urlopen('https://en.wikipedia.org/wiki/Prince_Harry,_Duke_of_Sussex')
    html = urlopen('https://en.wikipedia.org/wiki/Rembrandt')
    bs = BeautifulSoup(html, 'html.parser')
    images = bs.find_all('img', {'src':re.compile('.jpg')})
    for image in images:
        result_images.append("https:"+image['src']+'\n') #concatenation!
    return result_images

def titleextract(url):
    # Extract the part of the string between the last two "/" characters
    # Decode special URL characters and cut off the suffix
    # Replace all "_" with spaces
    return unquote(url[58:url.rindex("/", 58)-4]).replace('_', ' ')
{% for image, title in images_titles %}
    <div class="card" style="width: 18rem;">
      <img src="{{image}}" class="card-img-top" alt="...">
      <div class="card-body">
        <h5 class="card-title">{{title}}</h5>
        <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
        <a href="#" class="btn btn-primary">Go somewhere</a>
      </div>
    </div>
{% endfor %}


来源:https://stackoverflow.com/questions/62962025/jinja2-nested-for-loops-two-lists

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!