Filtering Django Databases - database

I am learning Django and am trying to filter names based off the database table: power_id. Is there anyway to filter based off power_id, or any variable in a database? Here is what I have so far. Note, I am using Twitter-Bootstrap
This is the Team View
<div class="accordion-inner">
<ul>
{% if User.object.power_id == 1 %}
<li>
<a href="#">
{{ user }}
</a>
</li>
{% endif %}
</ul>
</div>
Lets say, 1 is an Admin.
Here is my views.py:
# Home view
class home(generic.ListView):
template_name = 'users/home.html'
context_object_name = 'User_list'
context_object_name2 = 'Power_list'
def get_queryset(self):
return User.objects.order_by('username')
# Team view
class team(generic.ListView):
template_name = 'users/team.html'
context_object_name = 'User_list'
def get_queryset(self):
return User.objects.order_by('username')
context_object_name2 = 'Power_list'
def in_catagory(User, Admin):
return things.filter(Admin=Admin)

From what I can see, you have passed in a model that you have created called User. Now, I do not know if this is a model that you have actually created or if you are using django.contrib.auth.models.User. But, this is an attempt to show you how to work with views in django.
from django.views.generic import View
from django.shortcuts import render
from .models import User
class TeamView(View):
def get(self, request):
Users = User.objects.filter(power_id='123')
return render(request, 'something.html', {'Users': Users, })
What I've done here may look intimidating, but is actually quite simple. From what I can understand, you have a bunch of users, with an property called power_id. And you want to get that, you need to filter all your users for the users with the power_id that you want.
That is what the first line after the get function call does. the get function call is here because when you send a request to a page, like www.google.com, you are sending a get request.
Now, the render function is a shortcut function. What it does is this: first parameter is always request, the second parameter is the html file that you want it to render, and the third parameter is the information you are sending which is a dictionary.
Now coming to your template. You can simply loop through all your users, like so:
<div class="accordion-inner">
<ul>
{% for user in Users %}
<li>
<a href="#">
{{ user }}
</a>
</li>
{% endfor %}
</ul>
</div>

You can override the get_context_data method to add that other variable.
class TeamView(ListView):
template_name = 'users/team.html'
context_object_name = 'User_list'
model = User # You never set the model
def get_queryset(self):
return super('TeamView', self).get_queryset().order_by('username') # call the parent function
def get_context_data(self, *args, **kwargs):
context = super('TeamView', self).get_context_data(*args, **kwargs)
context['Power_list'] = self.get_queryset().filter(power_id=1)
return context
Now you also have a context variable Power_list with all of the users that have power_id == 1 that you can iterate over
<div class="accordion-inner">
<ul>
{% for user in Power_list %}
<li>
<a href="#">
{{ user }}
</a>
</li>
{% endfor %}
</ul>
</div>

I have found the answer to my own question. Turns out, it was much simpler than I thought it was. What I needed was to re-arrange the code, along with getting variables right.
<div class="accordion-inner">
<ul>
{% for name in User_list %}
{% if name.power_id == 1 %}
{{ name }}<br />
{% endif %}
{% endfor %}
</ul>
</div>
The views.py file didn't need to be edited at all.

Related

How can you loop through all of the children of a model?

In Django I am trying to loop through all of the children of my Todo model. But whenever I try to run it, it gives me an AttributeError that says "Manager isn't accessible via Todo instances". My code looks like this:
{% extends 'base.html' %}
{% block content %}
<h3>Tasks</h3>
{% for t in model.objects.all %} <!-- Error -->
<p>{{t.name}}</p>
{% endfor %}
{% endblock %}
{% block options %}
<li class="bg-light py-3 w-100 px-4 rounded text-nowrap fs-4">
<button class="text-decoration-none text-dark">Save</button>
</li>
{% endblock %}
I tried to just put the model in the context, and then I got an error in the HTML, so I figured out that it happened when I tried to reference 'model.objects.all'.
Inside of your view you need to specify what django should pass to the template. It does not serve the entire Database; therefore queries like in model.objects.all inside of your templates are not allowed.
Specify the queryset inside your views.py:
def todo_view(request):
context = {}
context['my_todos'] = my_todo_model.objects.all()
context['most_important_todo'] = my_todo_model.objects.get(pk=1)
# put your own logic inside the `.get` method above
return render(request, 'my_template.html' context)
And then access it inside of your template like so:
{% for t in my_todos %}
<p>{{ t.name }}</p>
{% endfor %}
{{ most_important_todo.name }}
Because we put a queryset inside of my_todos we can loop over it in the template. most_important_todo ist just a single object passed to the template, so we can access its properties (e.g. the name) directly.
Let me know how it goes

Having a following followers problem in Django "too many values.."

I'm about to finish a Django based project, and the last step of this project is to build a followers/following feature. I can unfollow someone I've followed manually from the admin, but I can't follow someone from my html view. It misses me just one tiny thing to add into my html code but I'm really stuck. My code
My Model:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
CREATOR = "CREATOR"
SUBSCRIBER = "SUBSCRIBER"
ROLE_CHOICES = (
(CREATOR, "Créateur"),
(SUBSCRIBER, "Abonné"),
)
profile_photo = models.ImageField(upload_to='profile_photos/', default='profile_photos/default.png', blank=True, null=True)
role = models.CharField(max_length=10, choices=ROLE_CHOICES, default=SUBSCRIBER)
follows = models.ManyToManyField('self', related_name='followers', symmetrical=False)
My Views:
#login_required
def abonnements(request):
user = request.user
followers = user.followers.all()
follows = user.follows.all()
if request.method == 'POST':
if request.POST.get('follow'):
if request.POST.get('follow') == user.username:
return render(request, 'blog/abonnements.html', {'followers': followers, 'follows': follows, "error": "You can't follow yourself!"})
try:
followed_user = User.objects.get(request.POST.get('follow'))
except User.DoesNotExist:
return render(request, 'blog/abonnements.html', {'followers': followers, 'follows': follows, "error": "User does not exist"})
else:
print(followed_user)
elif request.POST.get('unfollow'):
user.follows.remove(User.objects.get(pk=request.POST.get('unfollow')))
return render(request, 'blog/abonnements.html', {'followers': followers, 'follows': follows, "success": "You are no longer following " + request.POST.get('unfollow')})
return render(request, 'blog/abonnements.html', {'followers': followers, 'follows': follows})
My HTML
{% extends 'base.html' %}
<title>{% block title %}Abonnements{% endblock %}</title>
{% block content %} {% include 'partials/_navbar.html' %}
<main class="corps_abonnements">
<section class="suivre">
<p class="suivre_utilisateurs_titre">Suivre d'autres utilisateurs</p>
<form method="post">
{% csrf_token %}
<input type="text" name="follow" value="">
<input type="submit" value="Envoyer">
</form>
</section>
<section class="abonnements">
<p color="red">{{ error }}</p>
{% if success %}<p color="green">{{ success }}</p>{% endif %}
<p class="abonnements_titre">Abonnements</p>
{% for user in follows %}
<div class="utilisateur_desabonner_container">
<p class="nom_utilisateur_desabonner">{{ user.username }}</p>
<form method="post">
{% csrf_token %}
{% if user in follows %}
<input type="hidden" name="unfollow" value="{{ user.id }}">
<button style="background-color:red;" type="submit" class="creer_critique_demande">
Se désabonner
</button>
{% endif %}
</form>
</div>
{% endfor %}
</section>
<section class="abonnes">
<p class="abonnes_titre">Abonnés</p>
{% for user in followers %}
<div class="utilisateur_abonne_container">
<p class="nom_utilisateur_abonne">{{ user.username }}</p>
</div>
{% endfor %}
</section>
</main>
{% endblock %}
So when I put the connected user name in the input, it returns me the error "you can't follow yourself", it means that my code is good
the message
but If I try to put the username of another user I want to follow, it raises me an error. Can someone help me please ?
ValueError at /abonnements/
too many values to unpack (expected 2)
Request Method: POST
Request URL: http://127.0.0.1:8000/abonnements/
views.py, line 155, in abonnements
followed_user = User.objects.get(request.POST.get('follow'))

Photologue not showing images or thumbnails

I am not able to get photologue to show the images. What am I doing wrong?
development environment
django 2.1
python 3.5
osx, virtual_env, recent pip
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'mst/media/')
MEDIA_URL = "/media/"
urls
urlpatterns += [
...
url(r'^photologue/', include('photologue.urls', namespace='photologue')),
]
model
from photologue.models import Photo, Gallery
class PhotoExtended(models.Model):
photo = models.OneToOneField(Photo, on_delete=models.CASCADE, related_name='photo')
related_model = models.ForeignKey(MyModel, on_delete=models.CASCADE)
def __str__(self):
return self.photo.title
class GalleryExtended(models.Model):
gallery = models.OneToOneField(Gallery, on_delete=models.CASCADE, related_name='gallery')
related_model = models.ForeignKey(MyModel, on_delete=models.CASCADE)
def __str__(self):
return self.gallery.title
class based view
class MyModelList(ListView):
model = MyModel
template_name = "pictures.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['photos'] = PhotoExtended.objects.all()
context['galleries'] = GalleryExtended.objects.all()
return context
template (pictures.html):
{% block content %}
<ul>
{% for photoExtended in photos %}
<li>{{ photoExtended.photo.get_absolute_url }}</li>
<li>{{ photoExtended.photo.image }}</li>
<img src="/{{ photoExtended.photo.image }}" alt="{{ p.photo.title }}">
{% endfor %}
{% for gallery in galleries %}
<li></li>
{% endfor %}
shell response (per docs)
>>> from PIL import Image
>>>
notes
I migrated the database, and see the data in the database, and everything looks correct.
page renderings
photologue urls:
A single photo
the list of the photos
and the direct accessing of the image: (ra is the name in photologue, but em.jpeg is the file name)
and my view directly:
The template was wrong/outdated from an older version. Here is the correct usage in the template for an image within a list of images of type photologueExtended:
{% for photoExtended in photos %}
<!-- The link to the photologue template page with the photo and its gallery(s)-->
Link to page
<!-- The src link to the image thumbnail itself in the media url-->
<img src="{{ photoExtended.photo.get_thumbnail_url }}" />
<!-- The src link to the image itself in the media url-->
<img src="{{ photoExtended.photo.get_display_url }}" />
<!-- The photologue image's title/description/etc… -->
{{ photoExtended.photo.title }} <br>
{{ photoExtended.photo.description }} <br>
{% endfor %}
Also:
the url catchall in the main project urls.py was incorrect, and should be:
url(r'^$', indexView, name='indexView'),

Query returning every cover in db for each entry?

My query seems to be returning 1 entry for each cover. That is, if I have 3 covers in the database, then the query will return entry #1 three times with each of the different covers. Since I have 7 entries, I'm getting 21 results. How do I structure my query to return the cover associated with the entry?
Here's what I have:
#app.route('/list', methods=['GET', 'POST'])
def list():
entries = Book.query.order_by(Book.id.desc()).all()
cvr_entries = Cover.query.filter(Cover.book).all()
### Other queries I've tried ###
# cvr_entries = Cover.query.join(Cover.book).all()
# cvr_entries = Cover.query.filter(Cover.book.any())
# cvr_entries = Cover.query.filter(Cover.book.any()).all()
return render_template(
'list.html',
entries=entries,
cvr_entries=cvr_entries)
Here's the /list output page:
{% for entry in entries %}
{% for cvr in cvr_entries %}
<article class="entry">
<img src="/static/data/covers/{{ cvr.name }}" alt="Cover for {{ entry.title }}" />
<ul class="entry-info">
<li class=""><h2>{{ entry.title }}</h2></li>
<li class="">Summary: {{ entry.summary|truncate( 30, true ) }}</li>
</ul>
</article>
{% endfor %}
{% endfor %}
Switching the order of the entries and cvr_entries for loops changes nothing. I've also tried adding first() instead of all(), but that leads to an error where it says
TypeError: 'Cover' object is not iterable
so that was a bust. I don't understand how to build the query.
Here is my model, as requested by #jonafato:
book_to_cover = db.Table('book_to_cover',
db.Column('cover_id', db.Integer, db.ForeignKey('cover.id')),
db.Column('book_id', db.Integer, db.ForeignKey('book.id'))
)
class Book(db.Model):
__tablename__ = 'book'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String())
summary = db.Column(db.Text)
book_to_cover = db.relationship('Cover', secondary=book_to_cover,
backref=db.backref('book', lazy='dynamic'))
def __repr__(self):
return "<Book (title='%s')>" % (self.title)
class Cover(db.Model):
__tablename__ = 'cover'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String())
def __repr__(self):
return "<Cover (name='%s')>" % self.name
Generally, you iterate over the model-- your relationships should allow you to do:
books = Book.query.all()
return render_template('list.html', books=books)
Then in your Jinja2 list.html template:
{% for book in books %}
<h3>{{ book }}</h3>
<ul>
{% for cover in book.book_to_cover %}
<li>{{ cover }}</li>
{% endfor %}
</ul>
{% endfor %}
It'd be more natural to rename the book_to_cover to covers to make it more like natural language when you access the model.

Can't fetch database objects when extending to another twig template in Symfony2

I'm new to Symfony2 (with knowledge in 1.2-1.4) and having little trouble trying to fetch some objects from the DB. I have a base template (index.html.twig) which have the following code block:
<nav>
<ul class="menu">
<li><a class="active" href="index.html">Home Page</a></li>
{% for category in categories %}
<li>{{ category.name }}</li>
{% endfor %}
<li class="last-item">Contact Us</li>
</ul>
</nav>
The method fetching categories is inside DefaultController:
public function indexAction()
{
$em = $this->getDoctrine()->getEntityManager();
$categories = $em->getRepository('XxxYyyBundle:Category')->findAll();
$genres = $em->getRepository('XxxYyyBundle:Genre')->findAll();
echo $categories.$genres;
return array('categories' => $categories, 'genres' => $genres);
}
If I access the page from Default it works perfectly, but if I try to access from another page that extends the template (using {% extends "XxxYyyBundle:Default:index.html.twig" %}) I get the following error:
Variable "categories" does not exist in XxxYyyBundle:Default:index.html.twig at line 53
I tried all the options included in the book (% include, etc) with the only conclusion that from another pages indexAction() is not executed. I think that fetching items from the DB to include them in a menu is something usual, so if someone is familiar to this matter I'll be very grateful for any help.
Thanks.
The easiest way is to place a render tag in your layout and reference a controller that runs the queries and renders the menu fragment.
{% render 'SomeBundle:Menu:menu' %}

Resources