Django Get Primary + Foreign Attributes - python

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

For if Loop ManyToMany Field Django

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 %}

Select One Column Using Peewee

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.

Trying to display a list of youtube videos into django template with django-embed-video

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 %}

How to determine wagtail Page content type within django template?

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 %}

Django, variable {{ }} inside {% %}

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 %}

Categories