I have two models: Site and Metric.
I want to display the Metric values alongside each Site.
My views.py is as follows:
from django.shortcuts import render
from .models import Site, Metric
def site_graph(request):
sites = Site.objects.order_by('name')
metrics = [s.metric_set.all() for s in sites]
return render(request, 'da/site_graph.html', {'sites': sites, 'metrics': metrics})
And my template content looks like this:
{% block content %}
{% for metric in metrics %}
[
{% for query in metric %}
{{ query.domain_authority }}
{{ query.date_queried }}
{% endfor %}
]
{% endfor %}
{% endblock content %}
I am not sure how I would go about getting the data I need in Django.
This data is going to be eventually passed onto d3.js for visualization which is why I need the data from the matching the primary key for each Site to be together.
You can use a list of dictionaries:
def site_graph(request):
metrics=[]
sites = Site.objects.order_by('name')
for site in sites:
metrics_site={}
metrics_site["site"] = site
metrics_site["metrics"] = site.metric_set.all()
metrics.append(metrics_site)
return render(request, 'da/site_graph.html', {'metrics': metrics})
And then in the template:
{% block content %}
{% for metric in metrics %}
{{ metric.site.name }}
{% for query in metric.metrics %}
{{ query.domain_authority }}
{{ query.date_queried }}
{% endfor %}
{% endfor %}
{% endblock content %}
metric.site.name is just an example if your model "site" contains a field "name" that you want to show.
Related
How can I query a manytomanyfield in a Django template? For example,
this if statement doesn't work, but this shows what I'd like to do:
Model:
class Product(models.Model):
Category = models.ManyToManyField(Category)
Template:
{% for p in Product %}
{% if p.Category_id == 6 %}
{{p.id}}
{% endif %}
{% endfor %}
I think it's better to filter your queryset in views.py as
products = Product.objects.filter(Category__id=6)
then loop through that queryset in template
{% for p in products %}
{{p.id}}
{% endfor %}
I don't know the actual use case. You haven't posted the view. Assuming in django template products is the queryset. e.g products= Product.objects.all(). This is how you will detect the Category instance with id=6 for all the products in django template.
{% for p in products %}
{% for category in p.Category.all %}
{% if category.id == 6 %}
{{p.id}}
{% endif %}
{% endfor %}
{% endfor %}
I have selected one column by using the peewee, and then send it to the template. But nothing return.
I have one table named Entry, with column tag_name.
#app.route('/archive')
def tag():
query_tag = (Entry.select(Entry.tag_name)).distinct())
return object_list('t.html', query_tag, check_bounds=False)
The corresponding template:
{%block content %}
{% for tag in object_list %}
<p>{{ tag }}</p>
{% endfor %}
{% endblock %}
And finally it display "None"
result_photo
But if I change to below code, it can work,:
#app.route('/archive')
def tag():
query_tag = (Entry.select().distinct())
return object_list('t.html', query_tag, check_bounds=False)
And the template:
{%block content %}
{% for tag in object_list %}
<p>{{ tag.tag_name }}</p>
{% endfor %}
{% endblock %}
You can combine your two examples and the following should work:
query_tag = Entry.select(Entry.tag_name).distinct()
And the template:
{% for entry in object_list %}
<p>{{ entry.tag_name }}</p>
{% endfor %}
Because, even though you've only selected one column, Peewee will still be returning Entry objects. The Entry objects will only have the "tag_name" field populated, though.
I am trying to embed a list of youtube videos, in which more videos will be added over time, into my django app using django-embed-video. Going after their documentation I did the following:
models.py
from embed_video.fields import EmbedVideoField
class Youtube(models.Model):
video = EmbedVideoField()
slug = models.SlugField(max_length=200, db_index=True, unique=True)
def __str__(self):
return self.video
admin.py
from .models import Youtube
from embed_video.admin import AdminVideoMixin
class YoutubeAdmin(AdminVideoMixin, admin.ModelAdmin):
list_display = ('video', 'slug')
admin.site.register(Youtube, YoutubeAdmin)
views.py
from .models import Youtube
def display_video(request):
videos = Youtube.objects.all()
context = {'videos': videos}
return render (request, 'scienceblog/post/videos.html', context)
videos.html
{% extends "base.html" %}
{% load embed_video_tags %}
{% video item.video 'small' %}
{% block content %}
{% if videos %}
{% for v in videos %}
{{ v }}
{% endfor %}
{% else %}
<p>No videos yet</p>
{% endif %}
{% endblock %}
Everything works perfect in the admin site. The youtube links are added and the videos are displayed. However I am very unsure about the HTML tags. The browser only displays the youtube links as a string when videos.html is rendered. How can I display the videos?
Thanks for the quick answer raratiru! It brought me on the idea to look into the code of the django-embed-video app itself. I fiddled around with it a bit and now it works just how I wanted it to work. The relevant code is:
videos.html
{% load embed_video_tags %}
{% for v in videos %}
{% video v.video as my %}
<iframe width="{{ 480 }}" height="{{ 320 }}" src="{{ my.url }}"
frameborder="0" allowfullscreen></iframe>
{% endvideo %}
{% endfor %}
You need to acquire the EmbedVideoField() which is video according to models.py. Therefore, the loop should read something like:
{% extends "base.html" %}
{% load embed_video_tags %}
{% video item.video 'small' %}
{% block content %}
{% if videos %}
{% for v in videos %}
{{ v.video }}
{% endfor %}
{% else %}
<p>No videos yet</p>
{% endif %}
{% endblock %}
It is possible that the EmbedVideoField() has more attributes that have to be accessed, you have to check the relevant docs. For example, if the embed code is stored in EmbedVideoField().embed_code you can reach it as such:
{% for v in videos %}
{{ v.video.embed_code }}
{% endfor %}
The core problem is that handling of wagtail RichTextField and StreamField is radically different in the templates.
I'm trying to accomplish something similar to the following:
{% with post=post.specific %}
{% if post.content_type == 'streamfield' %}
{% include_block post.body %}
{% else %}
{{ post.body|richtext }}
{% endif %}
{% endwith %}
I'm using Django-instagram for simply display Instagram content on my webpage:
{% load instagram_client %}
{% instagram_user_recent_media intel %}
This example works perfect, but the problem is Instagram name changes depending on selected page. I pass it via context:
def about(request, foo_id):
article = get_object_or_404(Bar, id=foo_id)
return render_to_response('about.html', {'foo' : article})
It works fine if I'm using it without template:
<p>{{ foo.instagram }}</p> --> returns valid name
How can I pass my "foo.instagram" like this:
{% load instagram_client %}
{% instagram_user_recent_media {{ foo.instagram }} %}
You can use set:
{% set new_var = foo.instagram -%}
{% load instagram_client %}
{% instagram_user_recent_media new_var %}