Twitter/Reddit posts not embedding properly on Django template - python

I'm building a news aggregator. I am connected to the twitter and reddit APIs through the tweepy and PRAW libraries. I'm pulling json data from twitter and reddit, and displaying posts in a timeline format side by side.
I have one template called main.html which takes in context(reddit post ids; twitter status urls) and passes that context to template tags, in order to generate html to embed. Here is the template where all this work is being done. The template tags are 'tweet_tags.py' and 'red_attempt.py' as you can see loaded at the top of the page.
{% block content %}{% load red_attempt %} {% load tweet_tags %} {% autoescape off %}
<h1>Welcome</h1>
Refresh News
<div class="container">
<div class="row">
<div class="col-6">
<h3 class='text-center'>Reddit News</h3>
{% for item in reddit %}
<div class="mdl-card__media" id="timeline"></div>
{% red_attempt item %}
<br>
{% endfor %}
</div>
<div class="col-6">
<h3 class='text-center'>Twitter News</h3>
{% for item in twitter %}
<div class="mdl-card__media" id="timeline"></div>
{% tweet_tags item %}
<br>
{% endfor %}
</div>
</div>
</div>
{% endautoescape %}{% endblock %}
The template tags are 'tweet_tags.py' and 'red_attempt.py' as you can see loaded at the top of the page.
Here is their code, respectively:
tweet_tags.py
def tweet_tags(url):
""" Requests a tweet from oembed and returns the html element """
tweet_request = requests.get(
'https://publish.twitter.com/oembed?url=' + url + '&omit_script=true')
tweet_json = tweet_request.json()
tweet_html = tweet_json['html']
return tweet_html # returns to our template
red_attempt.py
def red_attempt(url):
""" Requests a tweet from oembed and returns the html element """
headers = {
'User-Agent': 'nba_comp app',
'From': 'nickiscool88',
'Accept': 'application/json'
}
endpoint = requests.get(
f"https://www.reddit.com/oembed?url=https://www.reddit.com{url}", headers=headers)
return endpoint.json()['html']
This all works as expected.
What I want to do, is instead, have a services script pull the twitter and reddit data, store that data in my database with models.py then pull the data from the local database to display. I'm trying to do that in this script, test.html
{% block content %} {% autoescape off %}
{% for post in all %}
<div class="mdl-card__media" id="timeline"></div>
<p>{{ post.html }}</p>
</div>
{% endfor %} {% endautoescape %}{% endblock %}
In this case, "all" is the context, which is a database object from models.py. Here is my models.py script.
class Post(models.Model):
post_type = models.CharField(
max_length=20, null=True, blank=True)
root_url = models.CharField(max_length=200, default="", unique=True)
html = models.TextField(default="")
created_at = models.DateTimeField(auto_now_add=True)
So as you can see, I'm trying to loop through all the posts in my database, and post the html of each post. I'm expecting the same result as main.html, but instead, it looks like this
as opposed to main.html which looks like this
All the script/widget tags that support embedding are at the bottom of the HTML templates.
How can I display these twitter/reddit posts from my database in test.html similar to how I can display them like main.html, where I'm just fetching the json data?

Issue solved. The script tags used for embedding twitter/reddit posts needs to be inside the tag.

Related

How can I open a page with only one django model object's info after clicking it's ImageField on another page?

I am displaying django models on one of my website's pages. When I press one's ImageField on the page, I want it to open another page including only that one object. How do I do that ?
I thought about using the filter method in my views.py for filtering through my objects and finding that exact one, but I don't know what arguments to use.
Any ideas? (I am a beginner in django)
VIEWS.PY
from django.shortcuts import render
import requests
from . import models
def index(request):
return render(request, 'base.html')
def new_search(request): ********NOT IMPORTANT (I THINK)********
search = request.POST.get('search')
models.Search.objects.create(search=search)
objects = models.Object.objects.all()
results = objects.filter(name__contains=search).all()
args = { 'results': results }
return render(request, "my_app/new_search.html", args)
def individual_page(request):
link = request.GET.get('object-link')
objects = models.Object.objects.all()
return render(request, "my_app/individual_page.html")
MY TEMPLATE
{% extends "base.html" %}
{% block content %}
{% load static %}
<h2 style="text-align: center">{{ search | title }}</h2>
<div class="row">
{% for result in results %}
<div class="col s4">
<div class="card medium">
<div class="card-image">
<a name="object-link" href="{% url 'individual_page' %}"><img src="{{ result.image.url }}" alt=""></a>
</div>
<div class="card-content">
<p>{{result.name}}</p>
</div>
<div class="card-action">
View listing: Price TEST
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
So, the thing I want to do is: when I press the anchor tag that includes the image, I get redirectioned to another page which contains only that one object's info.

Django- understanding how information is displayed on webpage

I have recently taken over the development of a Django/ Python project, and am looking into fixing a particular bug within the system as it currently stands.
There is a database of projects with quite a large amount of information about each project stored. On one of the webpages, there is a button, which when clicked will add a new form to the page- the form allows the user to enter some details about a new object for the given project. If there are existing objects for that project within the database, a 'table' will be displayed with a form on each row for each of the existing objects, and the user can manually update the fields in the form to update the information about each of the objects in the database. They can also add a new 'row' to the 'table' to create a new object to add to that project.
This page is displayed by the view:
def current_ccis(request, budget_id):
"""
View the CCIs for the current budget
"""
budget = Budget.objects.select_related('project').get(id=budget_id)
project = budget.project
ccis = CciItem.objects.select_related('budget', 'budget__project', 'project_room', 'project_room__room').filter(budget_id=budget_id).order_by('project_room__order', 'created')
formset = CciItemFormset(queryset=ccis.exclude(name=None), form_kwargs={'project':project})
context = {
'ccis': ccis,
'project': project,
'budget': budget,
'formset': formset,
'widths': ['60px', '120px', '220px', '120px', '60px', '60px', '60px', '280px', '280px'],
}
return render(request, 'costing/ccis_current.html', context)
The first cell in each form of the formset for each object displays the 'type' of object that it is, and every other cell displays/ stores other information relevant to the object itself.
On another one of the webpages, there is then a report displayed about a given project which includes information based on what the user input into the forms on the page displayed by the view current_ccis(request, budget_id)
This page is displayed by the view:
def report_ccis(request, project_id):
""" CCI items styled for pdf """
project = Project.objects.get(id=project_id)
budget = get_current_budget(project_id)
cci_total_exc = budget.cci_total_exc_vat_final
cci_grouped_items = budget.cci_items.all().order_by('project_room', 'name')
context = {
'project': project,
'cci_total_exc': cci_total_exc,
'cci_grouped_items': cci_grouped_items,
'webview': 1,
}
try: context['current_budget'] = project.budget_versions.get(current_marker=1) #For option name/date on top of pdfs
except ObjectDoesNotExist: pass
if request.GET.get('stage') == 'pd':
""" Render post deposit homepage """
context['html'] = render_to_string('costing/report2_ccis.html', context)
context['active_tab'] = '4'
return render(request, 'costing/reports_post_deposit.html', context)
else:
""" Render pre deposit homepage """
context['html'] = render_to_string('costing/report_ccis.html', context)
context['active_tab'] = '5'
return render(request, 'costing/reports_pre_deposit.html', context)
and the report currently displays the information in the format:
Title
Project ID
Object
detail
detail
Object
detail
i.e. a list of Objects belonging to the project, and underneath 'Object title' a list of details belonging to that object.
The issue that I'm having here, is that for some projects, the 'Object' names are all displayed with their 'details' listed beneath each 'Object', but for others, the details are not listed under their respective 'Objects', but rather all listed under one 'Object', which is titled "None"...
What I don't understand, is why there is this inconsistency- why is that for some projects, the 'Object' names are shown on the report, with all of the 'details' listed under their respective 'Objects', but for other projects, all of the 'details' are listed under the Object 'None'...?
Anyone have any suggestions why this is?
Edit
The reports are displayed in the HTML files with:
(post deposit):
{% block tabs %}
{% with 'Payment schedule,Agreed variations,Variations not yet finalised,Client choice items,Overview'|listify as tabs %}
{% for tab_name in tabs %}
{% with forloop.counter as tab %}
{% if not tab == active_tab|add:0 %}<a class="tab" href="{% url 'costing:report2_tabbed' project.id %}?tab={{tab}}">{% else %}<a class="active tab">{% endif %}{{tab_name}}</a>
{% endwith %}
{% endfor %}
{% endwith %}
{% endblock tabs %}
(pre deposit):
{% block tabs %}
{% with 'Overview, Construction budget, Schedule of works, Client choice items'|listify as tabs %}
{% for tab_name in tabs %}
{% with forloop.counter as tab %}
{% if not tab == active_tab|add:0 %}<a class="tab" href="{% url 'costing:report_tabbed' project.id %}?tab={{tab}}">{% else %}<a class="active tab">{% endif %}{{tab_name}}</a>
{% endwith %}
{% endfor %}
{% endwith %}
{% endblock tabs %}
Edit
The files where this HTML comes from both extend from the same HTML file (reports_tabbed.html), which has the following HTML:
{% extends "base.html" %}
{% load staticfiles utilities %}
{% block head_extras %}
<link rel="stylesheet" type="text/css" href="{% static "moon/scss/pdf-reports.css" %}">
{% endblock head_extras %}
{% block page_options %}
{% if request.user.first_name in 'Becky,Duncan'|listify and project.deposit_received %}
Make quick PDF
{% endif %}
{% endblock page_options %}
{% block content %}
<div class="tabbed m-r-lg text-sm">
<div class="navbar tabbed text-sm">
{% block tabs %}
{% endblock tabs %}
</div>
<div class="tabbed-section border {% block tabbed_class %}page{% endblock tabbed_class %}">
{{html}}
</div>
</div>
{% endblock content %}
{% block content_scripts %}
{% endblock content_scripts %}

How do you add similar posts to a detail page using django

I tried to show similar posts to an article in an aside column. A feauture sites like youtube and even stack overflow. Not having anyone to ask about it, I assumed articles listed on the side were ones with similar tags. But it's not working its saying nothing matches. this is what I had in my post_detail.html:
{% block content %}
<div class="row" style="margin-top: 70px">
<div class="col-sm-8">
{% if instance.image %}
<img src='{{ instance.image.url }}' class="img-responsive" />
{% endif %}
<p>Share on:
<a href="https://www.facebook.com/sharer/sharer.php?u={{ request.build_absolute_uri }}">
Facebook
</a>
<a href="https://twitter.com/home?status={{ instance.content | truncatechars:80 | urlify }}%20{{ request.build_absolute_uri }}">
Twitter
</a>
<a href='https://plus.google.com/share?url={{ request.build_absolute_uri }}'></a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url={{ request.build_absolute_uri }}&title={{
instance.title }}&summary={{ share_string }}&source={{ request.build_absolute_uri }}">
Linkedin
</a>
</p>
<h1>{{ title }}<small>{% if instance.draft %}<span style="color:red"> Draft</span>{% endif %} {{instance.publish}}</small></h1>
{% if instance.user.get_full_name %}
<p>By {{ instance.user.get_full_name }}</p>
{% else %}
<p>Author {{ instance.user }}</p>
{% endif %}
<p><a href='{% url "posts:list" %}'>Back</a></p>
<p><a href='{% url "posts:delete" instance.id %}'>delete</a></p>
<p>{{instance.content | linebreaks }}</p>
<hr>
</div>
<div class="panel panel-default pull-right" style="height: 1000px">
<div class="panel-heading">
<h3 class="panel-title">Similar Articles</h3>
</div>
==========right here====================
<div class="panel-body">
{% for tag in instance.tags.all %}
<h4> {{ tag.title }} </h4><hr>
{% endfor %}
</div>
==========right here====================
</div>
</div>
{% endblock content %}
and this is my view
def post_detail(request, slug=None):
instance = get_object_or_404(Post, slug=slug)
if instance.publish > timezone.now().date() or instance.draft:
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
share_string = quote_plus(instance.content)
context = {
"title": "detail",
"instance": instance,
"share_string": share_string,
}
return render(request, "posts/post_detail.html", context)
if this approach is beyond syntax correction and needs to be rewritten. I don't mind writing it over the correct way. This is my second month working with Django. To me this way made sense but it's not working. And are sites like youtube which has a video and similar videos to the right of the main video, are those videos there because they share similar tags? any and all help is welcome.
In the long run and to not reinvent the wheel using a reusable Django application already tried and tested is the sensible approach. In your case there is such app: django-taggit
and is easy to use:
You install it
pip install django-taggit
Add it to your installed apps:
INSTALLED_APPS = [
...
'taggit',
]
Add its custom manager to the model on which you want tags
from django.db import models
from taggit.managers import TaggableManager
class YourModel(models.Model):
# ... fields here
tags = TaggableManager()
and you can use it in your views:
all_tabs = instance.tags.all()
It even has a similar_objects() method which:
Returns a list (not a lazy QuerySet) of other objects tagged similarly
to this one, ordered with most similar first.
EDIT
To retrieve similar posts you should use:
similar_posts = instance.tags.similar_objects()
and to get only the first, let's say, 5 similar posts:
similar_posts = instance.tags.similar_objects()[:5]
where instance is a instance of the Post model.
you should let us know what is not matching.
your post_detail tries to find a Post with a tag's slug.
instance = get_object_or_404(Post, slug=slug)
I doubt that's what you intended.
get_object_or_404 either tries to find an exact match or raise error.
Since your original post has the tag, you will be getting the same post or multiple.
The following block of code is not what you said you wanted either.
{% for tag in instance.tags.all %}
<h4> {{ tag.title }} </h4><hr>
{% endfor %}
It lists all tags of the original post, doesn't list related post (via tag)
If you want to show related post, and you intent to use tag to define relatedness, define a method in your post model to return such related posts.
def get_related_posts_by_tags(self):
return Post.objects.filter(tags__in=self.tags.all())
are those videos there because they share similar tags?
Not sure how they judge the relatedness, you should ask that in a separate question.
If I have to guess, it would be more than just tag comparison though.
** edit
Actually, proper term for relatedness is similarity.
You might find further info by googling document similarity.
{% for post in instance.get_related_post_by_tag %}
// href to post.absolute_url
{% endfor %}

Getting user by primary key in flask

I'm working with flask and have a html page that contains of user name(user.html) which took from table, Now How can I see more detail by clicking on each of users(which route to profile)?
I don't use login for app So I don't want to use g
app.py
# am I doing it right?
#app.route('/profile/<int:id>')
def profile(id=None):
detail = Contacts.query.get(id)
return render_template('profile.html', detail= detail , id=id)
user.html
{% extends "layout.html" %}
{% block content %}
<h2>show user</h2>
{% for contact in contact %}
# I got error when I click on each user name to see their 'profile'
#I guess because of id How can Solve it?
#error BuildError: ('profile', {}, None)
<strong>name:</strong><a href={{url_for('profile')}}>
{{ contact.name}}</a><br>
{% endfor %}
{% endblock %}
profile.html
{% extends "layout.html" %}
{% block content %}
<h2>show user profile</h2>
# how can I make it specific for each row of table(each user)?
{% for detail in Contacts %}
<strong>name:</strong> {{ detail.name}} <br>
<strong>email:</strong> {{ detail.email }} <br>
<strong>age:</strong> {{ detail.age}} <br>
<br>
{% endfor %}
{% endblock %}
model.py
class Contacts(db.Model):
__tablename__ = "Contacts"
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(50))
email = db.Column(db.String(50))
age = db.Column(db.Integer)
submit = SubmitField("Submit")
I noticed two things in your code:
# this
<a href={{url_for('profile')}}>
# should be
<a href={{url_for('profile', id=contact.id)}}>
# otherwise Flask can't find the route, because it needs an id
And the other one:
{% for detail in Contacts %}
There is no such thing as a Contacts variable in your template, because your view function does not send it. Just get rid of the loop and use detail directly, because it's what you sent to the template.

URLs being produced correctly but not directing to correct template

I'm trying to follow the Simple Blog tutorial at Django By Example. I've managed to get as far as producing a site that loads correctly, but while the index view is loading find, and the links to the individual posts show up and appear to be formatted correctly, they point back to the index template so all that happens when you click on them is that it reloads the index view. I'm new to Django and the tutorial is sparse to say the least and not helped by the fact it's written for an old version of Django and I'm using 1.5. I've been staring at it all afternoon and I'm pretty lost.
Here's my urls.py
from django.conf.urls import patterns, url
from blog import views
urlpatterns = patterns('blog.views',
#index
(r"$", 'main'),
#ex: /1/
(r"^(\d+)/$", 'post'),
#ex: /add_comment/1/
(r"^add_comment/(\d+)/$", 'add_comment'),
)
my views.py
from blog.models import Post, PostAdmin, Comment, CommentAdmin
class CommentForm(ModelForm):
class Meta:
model = Comment
exclude = ["post"]
def main (request):
"""Main Listing."""
posts = Post.objects.all().order_by("-created")
paginator = Paginator(posts, 10)
try: page = int(request.GET.get("page", '1'))
except ValueError: page = 1
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = patinator.page(paginator.num_pages)
return render_to_response("blog/list.html", dict(posts=posts, user=request.user))
def post (request, pk):
"""single post with comments and comment form"""
post = Post.objects.get(pk=int(pk))
comments = Comment.objects.filter(post=post)
d = dict(post=post, comments=comments, form=CommentForm(), user=request.user)
d.update(csrf(request))
return render_to_response("blog/post.html", d)
and the list.html that contains the links that aren't going anywhere!
{% extends "blog/bbase.html" %}
{% block content %}
<div class="main">
<!-- Posts -->
<ul>
{% for post in posts.object_list %}
<div class="title">{{ post.title }}</div>
<ul>
<div class="time">{{ post.created }}</div>
<div class="body">{{ post.body|linebreaks }}</div>
<div class="commentlink">Comments</div>
</ul>
{% endfor %}
</ul>
<!-- Next/Prev page links -->
{% if posts.object_list and posts.paginator.num_pages > 1 %}
<div class="pagination" style="margin-top: 20px; margin-left: -20px; ">
<span class="step-links">
{% if posts.has_previous %}
newer entries <<
{% endif %}
<span class="current">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}
</span>
{% if posts.has_next %}
>> older entries
{% endif %}
</span>
</div>
{% endif %}
</div>
{% endblock %}
The Django URL resolver will return the first URL pattern that matches the incoming request. The regex for your 'main' view r"$" will match ANY incoming request since you are only looking for $ which is an end of string character.
You need to alter your 'main' URL regex to be r'^$'.
Alternatively, if you would like a catch-all view, you could move the 'main' view to the bottom of your URLs

Categories