在 Django 网页中嵌入来自用户提交评论的 YouTube 视频
Embedding YouTube Videos from User Submitted Comments in Django Webpage
我正在用 Django 制作一个博客网页,我允许对博客文章发表评论。当用户提交评论时,我可以在我的评论模型中使用一个函数来识别他们在文本中包含的 links。我还可以使用 iframe 和用户在评论中的 url 列表将视频嵌入回模板中。我遇到的问题是我想在 link 中用户键入的完全相同的位置显示嵌入式视频。例如,如果用户键入一段文本,然后粘贴到 YouTube link,然后他们再键入一段,我希望视频嵌入在段落之间。我已经尝试了几件事,但我还没有弄明白。我很感激我得到的任何答案。这是评论模型的代码:
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
这是我的模板中处理评论的部分:
<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>
有没有人对如何在用户将 link 放在文本中的位置嵌入视频有任何想法?
Previously, I explained such as below because I created an issue 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'}
]
>>
然后,用模板标签处理。下面这个脚本还没有完成,你需要删除标签,例如<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)
我正在用 Django 制作一个博客网页,我允许对博客文章发表评论。当用户提交评论时,我可以在我的评论模型中使用一个函数来识别他们在文本中包含的 links。我还可以使用 iframe 和用户在评论中的 url 列表将视频嵌入回模板中。我遇到的问题是我想在 link 中用户键入的完全相同的位置显示嵌入式视频。例如,如果用户键入一段文本,然后粘贴到 YouTube link,然后他们再键入一段,我希望视频嵌入在段落之间。我已经尝试了几件事,但我还没有弄明白。我很感激我得到的任何答案。这是评论模型的代码:
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
这是我的模板中处理评论的部分:
<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>
有没有人对如何在用户将 link 放在文本中的位置嵌入视频有任何想法?
Previously, I explained such as below because I created an issue 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'}
]
>>
然后,用模板标签处理。下面这个脚本还没有完成,你需要删除标签,例如<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)