【问题标题】:Embedding YouTube Videos from User Submitted Comments in Django Webpage在 Django 网页中嵌入来自用户提交评论的 YouTube 视频
【发布时间】:2017-02-10 18:32:06
【问题描述】:

我正在使用 Django 制作博客网页,并且我已允许 cmets 用于博客文章。当用户提交评论时,我可以使用评论模型中的函数来识别他们包含在文本中的链接。我还可以使用 iframe 和用户在评论中的 url 列表将视频嵌入回模板中。我遇到的问题是我想在用户在链接中键入的完全相同的位置显示嵌入的视频。例如,如果用户输入一段文本,然后粘贴到 YouTube 链接中,然后他们又输入了一段,我希望将视频嵌入到段落之间。我已经尝试了几件事,但我还没有弄清楚。我很感激我得到的任何答案。这是评论模型的代码:

class Comment(models.Model):

    post = models.ForeignKey('forum.Thread', related_name='comments')
    username = models.CharField(max_length=20,default='guest')
    text = models.TextField()
    created_date = models.DateTimeField(default=timezone.now)
    approved_comment = models.BooleanField(default=False)

    def approve(self):
        self.approved_comment = True
        self.save()

    def __str__(self):
        return self.text

    def get_youtube_urls(self):
        urls = []
        youtube_regex = (
            r'(https?://)?(www\.)?'
            '(youtube|youtu|youtube-nocookie)\.(com|be)/'
            '(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})')

        matches = re.findall(youtube_regex, self.text)

        for url in matches:
            urls.append(url[5])

        return urls

这是我的模板中处理 cmets 的部分:

<div class="comment">
    <strong>Reply from user {{ comment.username }}</strong>
    <p>{{ comment.text|linebreaks|urlize }}</p>
    {% if comment.get_youtube_urls %}
        {% for url in comment.get_youtube_urls %}
            <div style="position:relative;height:0;padding-bottom:56.25%"><iframe src="https://www.youtube.com/embed/{{url}}?ecver=2" width="640" height="360" frameborder="0" style="position:absolute;width:50%;height:50%;left:0" allowfullscreen></iframe></div>
        {% endfor %}
    {% endif %}
    <div class="date">{{ comment.created_date }}</div>
</div>

有没有人对如何在用户在文本中放置链接的位置嵌入视频有任何想法?

【问题讨论】:

    标签: django youtube embed jinja2


    【解决方案1】:

    之前,我解释如下,因为我创建了一个问题save regex permalink not work well

    所以,如果你想测试它,你可以手动尝试。 我在http://www.pyregex.com 上检查你的正则表达式模式;

    1.模式:findall

    2. 模式:

    (https?://)?(www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})
    

    3. 测试字符串:

    https://youtu.be/yVpbFMhOAwE
    
    https://www.youtube.com/watch?v=8Z5EjAmZS1o
    
    https://www.youtube.com/embed/yVpbFMhOAwE
    
    <iframe width="560" height="315" src="https://www.youtube.com/embed/Tlf00NT6mig" frameborder="0" allowfullscreen></iframe>
    
    <iframe width="560" height="315" src="https://www.youtube.com/embed/KQzCxdO3hvo" frameborder="0" allowfullscreen></iframe>
    
    https://www.youtube.com/watch?v=VslLZcV9ZcU&list=RD8Z5EjAmZS1o&index=2
    

    4.结果:

    ["https://","","youtu","be","","yVpbFMhOAwE"]
    ["https://","www.","youtube","com","watch?v=","8Z5EjAmZS1o"]
    ["https://","www.","youtube","com","embed/","yVpbFMhOAwE"]
    ["https://","www.","youtube","com","embed/","Tlf00NT6mig"]
    ["https://","www.","youtube","com","embed/","KQzCxdO3hvo"]
    ["https://","www.","youtube","com","watch?v=","VslLZcV9ZcU"]
    

    我认为您应该这样做以获取视频 ID;

    def get_youtube_urls(self):
    
        youtube_regex = (
            r'(https?://)?(www\.)?'
            '(youtube|youtu|youtube-nocookie)\.(com|be)/'
            '(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})')
    
        matches = re.findall(youtube_regex, self.text)
    
        urls = []
        for url in matches:
            id = url[-1]        # from last index of `matches` list.
            if len(id) == 11:   # check if `id` is valid or not.
                urls.append(id)
        return urls
    

    如果不行,建议你把上面youtube_regex的值改成这个(不保存在元组里)

    youtube_regex = r'(https?://)?(www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})'
    
    # OR, recomended to use this;
    
    youtube_regex = r'http(?:s?):\/\/(?:www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})'
    

    更新

    为了得到正确的位置,我建议你使用finditer;

    >>> youtube_regex = r'http(?:s?):\/\/(?:www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})'
    >>> pattern = re.compile(youtube_regex)
    >>> [{'origin': m.group(), 'id': m.group(4), 'position': m.start()} for m in pattern.finditer(test_strings) ]
    [
      {'position': 0, 'id': 'yVpbFMhOAwE', 'origin': 'https://youtu.be/yVpbFMhOAwE'}, 
      {'position': 30, 'id': '8Z5EjAmZS1o', 'origin': 'https://www.youtube.com/watch?v=8Z5EjAmZS1o'}, 
      {'position': 75, 'id': 'yVpbFMhOAwE', 'origin': 'https://www.youtube.com/embed/yVpbFMhOAwE'}, 
      {'position': 156, 'id': 'Tlf00NT6mig', 'origin': 'https://www.youtube.com/embed/Tlf00NT6mig'}, 
      {'position': 280, 'id': 'KQzCxdO3hvo', 'origin': 'https://www.youtube.com/embed/KQzCxdO3hvo'}, 
      {'position': 366, 'id': 'VslLZcV9ZcU', 'origin': 'https://www.youtube.com/watch?v=VslLZcV9ZcU'}
    ]
    >>
    

    然后,用模板标签处理它。下面这个脚本还没有完成,你需要把&lt;iframe等标签去掉,或者从原文评论中去掉..

    import re
    from django import template
    from django.utils.safestring import mark_safe
    
    register = template.Library()
    
    def iframe_video(id):
        """
        return html string iframe video from the `id`.
        """
        return '<iframe src="https://www.youtube.com/embed/{}"></iframe>'.format(id)
    
    @register.filter
    def safe_comment(text_comment):
        """
        {{ comment.text|safe_comment|linebreaks|urlize }}
        """
        youtube_regex = (r'http(?:s?):\/\/(?:www\.)?'
                         '(youtube|youtu|youtube-nocookie)\.(com|be)/'
                         '(watch\?v=|embed/|v/|.+\?v=)?([^&=%\?]{11})')
        pattern = re.compile(youtube_regex)
        matches = [
            {'origin': m.group(), 'id': m.group(4), 'position': m.start()}
            for m in pattern.finditer(text_comment)
        ]
        for match in matches:
            id = match['id']
            origin = match['origin']
            position = match['position']
    
            # text_comment.replace(origin, iframe_video(id))
            # do something to replace tag <iframe, or else..
        return mark_safe(text_comment)
    

    【讨论】:

    • 好的,这将在列表中提供正确的值。但是如何将这些值放在模板内的正确位置呢?
    • 我认为您可以在自定义模板标签中使用finditer 处理它...请查看我的最新更新...
    • 好的,谢谢。我认为这会在我尝试时起作用。我需要更多地学习正则表达式,因为我对它不是很熟悉。
    猜你喜欢
    • 2013-08-22
    • 2018-01-27
    • 1970-01-01
    • 2012-01-02
    • 2012-11-07
    • 2012-02-04
    • 2017-09-01
    • 1970-01-01
    • 2013-02-08
    相关资源
    最近更新 更多