I have a question about images and imagefields. However, the default picture I chose does not show up, only a blank circle. This was my default picture
Models.py
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=255, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
def __str__(self):
return self.user.username
class ProfilePicture(models.Model):
user = models.ForeignKey(User)
image = models.ImageField(upload_to='profile_image', default='profile_image/Default.jpg')
Forms.py
class UploadPictureForm(forms.Form):
image = forms.ImageField()
profile.html
<div class="container">
<div id="left">
<div id="profilecard">
{% if user.userprofile.image %}
<img class="circular--square" src="{{ }}" width="200" height="200">
{% endif %}
<div id="info">
<br>
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
<p>#{{ user }}</p>
<p>{{ user.userprofile.city }}</p>
<p>{{ user.userprofile.website }}</p>
<p><i>{{ user.userprofile.description }}</i></p>
</div>
</div>
The src tag in profile.html was not filed. If you want a default image to be used you can put an else tag in the template and point the src to a static file.
<div class="container">
<div id="left">
<div id="profilecard">
{% if user.userprofile.image %}
<img class="circular--square" src="{{ user.userprofile.image.url }}" width="200" height="200">
{% endif %}
<div id="info">
<br>
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
<p>#{{ user }}</p>
<p>{{ user.userprofile.city }}</p>
<p>{{ user.userprofile.website }}</p>
<p><i>{{ user.userprofile.description }}</i></p>
</div>
</div>
</div>
</div>
There is error in your code that you cannot get image from inside userprofile model so you need to do this:
Change your:
{% if user.userprofile.image %}
to:
{% if user.profilepicture_set.count > 0 %}
Change src attrib of img tag to:
src="{{ user.profilepicture_set.all.0.image.url }}"
Fixed code:
<div class="container">
<div id="left">
<div id="profilecard">
{% if user.profilepicture_set.count > 0 %}
<img class="circular--square" src="{{ user.profilepicture_set.all.0.image.url }}" width="200" height="200">
{% endif %}
<div id="info">
<br>
<h3>{{ user.first_name }} {{ user.last_name }}</h3>
<p>#{{ user }}</p>
<p>{{ user.userprofile.city }}</p>
<p>{{ user.userprofile.website }}</p>
<p><i>{{ user.userprofile.description }}</i></p>
</div>
</div>
</div>
</div>
Using related_name on your ForeignKey in ProfilePicture class will customize profilepicture_set key of user
user = models.ForeignKey(User, related_name='image')
You can access it on template like
{% if user.image.count > 0 %}
<img class="circular--square" src="{{ user.image.all.0.image.url }}" width="200" height="200">
{% endif %}
Also you can use OneToOneField to ProfilePicture User field if profile picture will be only one:
user = models.OneToOneField(User)
and template:
{% if user.profilepicture %}
<img class="circular--square" src="{{ user.profilepicture.image.url }}" width="200" height="200">
{% endif %}
Related
I am working on a Django project that serves as a grocery store. I am trying to set it up so that when people click on checkboxes and press the confirm purchase button, then the values from the checkboxes will print to a new HTML template. The problem I am having is that when I go to the new template it doesn't print the values from the checkboxes.
Views.py
class PostListView(ListView):
model = Post
template_name = 'blog/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
def inventory(request):
products = request.POST.getlist('products')
for product in products:
a = Post.objects.get(title=product)
a.quantity = a.quantity -1
a.save()
print(products)
return render(request, 'blog/confirm.html')
Home.html
{% extends "blog/base.html" %}
{% block content %}
<form action="{% url 'inventory' %}" method="POST" id="menuForm">
{% for post in posts %}
{% if post.quantity > 0 %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2">{{ post.category }}</a>
</div>
<h2><a class="article-title" >{{ post.title }}</a></h2>
<p class="article-content"> Price: ${{ post.Price }}</p>
<p class="article-content"> Sale: ${{ post.Sale }}</p>
<input type="checkbox" id="product_{{ post.id }}" value="{{ post.title }}" form="menuForm" name="products" > Inventory count: {{ post.quantity }}
</input>
</div>
</article>
{% else %}
{% endif %}
{% endfor %}
<button type="submit" form="menuForm">Confirm Purchase</button>
</form>
{% endblock content %}
confirm.html
{% extends "blog/base.html" %}
{% block content %}
{% for post in posts %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2">{{ post.category }}</a>
</div>
<h2><a class="article-title" >{{ post.title }}</a></h2>
<p class="article-content"> Price: ${{ post.Price }}</p>
<p class="article-content"> Sale: ${{ post.Sale }}</p>
<input type="checkbox" id="product_{{ post.id }}" value="{{ post.title }}" form="menuForm" name="products" > Inventory count: {{ post.quantity }}
</input>
</div>
</article>
{% endfor %}
{% endblock %}
urls.py
path('list/', PostListView.as_view(), name='blog-home'),
path('confirm', views.inventory, name='inventory'),
It's happening because of this you did not passed posts on confirm.html page
def inventory(request):
posts = Post.objects.get(title=product)
products = request.POST.getlist('products')
for product in products:
a = Post.objects.get(title=product)
a.quantity = a.quantity -1
a.save()
print(products)
return render(request, 'blog/confirm.html',{'posts':posts})
I added another div to bottom half of my site but it is not showing up. I can get it to show up in a separate web page, but not when I paste the same code to the bottom of this web page. Check out code, thanks in advance for you efforts.
OK so I understand I need to make "blogs" available in views. I tried modifying the function that defines "blogs", I also tried adding a new function for the page but neither seemed to work. I updated the original post with my views.py.
all_blogs.html
{% extends 'blog/navBarFooter.html' %}
{% block content %}
<br>
<br>
{% for blog in blogs %}
<div class="col-lg-12 col-md-8">
<img src="{{ blog.summaryImage.url }}" height=190 width=350>
<p>{{ blog.category }}</p>
<a href="{% url 'pageOne' blog.id %}">
<h2>{{ blog.title }}</h2>
</a>
<p>By: {{ blog.by }} | {{ blog.date|date:'M d Y'|upper }}</p>
<p>{{ blog.summary }}</p>
<hr color="black">
</div>
{% endfor %}
{% endblock %}
pageOne.html:
{% extends 'blog/navBarFooter.html' %}
{% block content %}
<!-- *************SHOWING UP ON WEBPAGE******************* -->
<h1 class="text-center mt-3" id="blogdetailtitle">{{ blog.title }}</h1>
<h5 class="text-center mt-3" id="blogdetailtitle">By: {{ blog.by }} | {{ blog.category }}</h5>
<hr color="black">
<div class="col-lg-12 col-md-8">
<img id="imgLeft" src="{{ blog.pageOneImage.url }}" height=190 width=350>
<p id="textLeft">{{ blog.pageOne | safe }}</p>
<br>
<br>
<hr>
<img id="imgRight" src="{{ blog.pageTwoImage.url }}" height=190 width=350>
<p id="textLeft">{{ blog.pageTwo | safe }}</p>
<br>
<br>
<hr>
<img id="imgLeft" src="{{ blog.pageThreeImage.url }}" height=190 width=350>
<p id="textLeft">{{ blog.pageThree | safe }}</p>
<br>
<br>
<hr>
<img id="imgRight" src="{{ blog.pageFourImage.url }}" height=190 width=350>
<p id="textLeft">{{ blog.pageFour | safe }}</p>
<br><br><br><br>
<hr>
</div>
<!-- *************NOT SHOWING UP ON WEBPAGE******************* -->
{% for blog in blogs %}
<div class="row">
<div class="col-lg-4 col-md-6">
<img src="{{ blog.summaryImage.url }}" height=190 width=350>
<p>{{ blog.category }}</p>
<a href="{% url 'pageOne' blog.id %}">
<h2>{{ blog.title }}</h2>
</a>
<p>{{ blog.date|date:'M d Y'|upper }}</p>
<p>{{ blog.summary }}</p>
</div>
{% endfor %}
</div>
{% endblock %}
views.py
from django.shortcuts import render, get_object_or_404
from .models import Blog
def all_blogs(request):
blogs = Blog.objects.order_by('category')
return render(request, 'blog/all_blogs.html', {'blogs': blogs})
def pageOne(request, blog_id):
blog = get_object_or_404(Blog, pk=blog_id)
return render(request, 'blog/pageOne.html', {'blog': blog})
def all_blogsT(request):
blogs = Blog.objects.order_by('category')
return render(request, 'blog/pageOne.html', {'blogs': blogs})
Your first half seems to be operating on a single blog variable, and not a list of blogs like in your second half.
So, consider removing the loop from your second half, and it should work.
If this is not the desired output you want, make sure you are using a list of blogs that actually contains elements for your second half. Currently it seems that your list blogs is either undefined or empty.
I'm new to Django so apologies if this one is silly. I have a Django template with three spots for images, and I'm trying to let an admin user choose which image in the database should go in which spot (left, middle or right). However,
My model looks like this:
from django.db import models
from django.urls import reverse
from django.utils.text import slugify
class Artwork(models.Model):
art = models.ImageField(upload_to='artworks/%Y')
title = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
date = models.DateField(auto_now_add=True)
herochoices = [('left', 'left'), ('middle', 'middle'), ('right', 'right')]
hero = models.CharField(choices=herochoices, max_length=6, unique=True, null=True, blank=True, error_messages={'unique':'Another artwork already uses this hero position.'})
slug = slugify(title, allow_unicode=False)
def get_absolute_urls(self):
return reverse('artwork_list', kwargs={'slug': self.slug})
And my template looks like this:
{% extends 'base.html' %}
{% block content %}
<div class="container">
<div class="row">
{% for artwork in object_list %}
{% if artwork.hero == 'left' %}
<div class="col-sm p-3 align-items-center">
<img class="img-fluid rounded" src="{{ artwork.art.url }}" />
<p>{{ artwork.hero }}</p> <!--for testing-->
</div>
{% elif artwork.hero == 'middle' %}
<div class="col-sm p-3 align-items-center">
<img class="img-fluid rounded" src="{{ artwork.art.url }}" />
<p>{{ artwork.hero }}</p> <!--for testing-->
</div>
{% elif artwork.hero == 'right' %}
<div class="col-sm p-3 align-items-center">
<img class="img-fluid rounded" src="{{ artwork.art.url }}" />
<p>{{ artwork.hero }}</p> <!--for testing-->
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endblock content %}
For some reason the images are displayed in the wrong order:
I have been looking at this for forever, any help is much appreciated!
The template you are generating with Django is not the following, since the for loop does simply follow the queryset items order.
<div class="container">
<div class="row">
<div class="col-sm p-3 align-items-center">
<img class="img-fluid rounded" src="{{ LEFT URL }}" />
<p>{{ LEFT HERO }}</p>
</div>
<div class="col-sm p-3 align-items-center">
<img class="img-fluid rounded" src="{{ MIDDLE URL }}" />
<p>{{ MIDDLE HERO }}</p>
</div>
<div class="col-sm p-3 align-items-center">
<img class="img-fluid rounded" src="{{ RIGHT URL }}" />
<p>{{ RIGHT URL }}</p>
</div>
</div>
</div>
In this snippet, three images will be ordered. If you have more than three, you should make the queryset "smarter" (i.e. a simple get won't work).
URL:
def example(request):
qs = Artwork.objects.all()
objects_list = [qs.get(hero=position) for position in ["left", "middle", "right"]]
return render("test.html", { "objects_list": objects_list})
HTML:
{% extends 'base.html' %}
{% block content %}
<div class="container">
<div class="row">
{% for artwork in object_list %}
<div class="col-sm p-3 align-items-center">
<img class="img-fluid rounded" src="{{ artwork.art.url }}" />
<p>{{ artwork.hero }}</p>
<!--for testing-->
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
In my site I have 2 sections for users. The user posts page and the profile page. The profile page has all their info on it, so username, description, first/last name, etc. And the user posts page has all their posts on it. However, I want to integrate them together somehow.
Here is some of the code.
Here is the view for the User Posts
class UserPostListView(ListView):
model = Post
template_name = 'mainapp/user_posts.html'
context_object_name = 'posts'
def get_queryset(self):
user = get_object_or_404(User,username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-published_date')
As you can see, I am returning the specific users posts.
And now here is my profile view
def view_profile(request,pk=None):
if pk:
user_profile = User.objects.get(pk=pk)
else:
user_profile = request.user
context = {'user':user_profile}
return render(request,'mainapp/profile.html',context)
It returns all the user's info.
Here is the HTML code for both the profile and user posts page
{% block content %}
<div class="profile-page-container">
<div class="profile-page-info">
<div class="profile-page-banner">
<div class="profile-page-banner-background">
<!-- <img src="https://cdn.pixabay.com/photo/2017/08/30/01/05/milky-way-2695569_960_720.jpg" alt="{{ user }}'s Background Image" > -->
</div>
<div class="profile-page-banner-text">
<h2 title="{{ user }}" id="username-profile-page">{{ user|safe|linebreaksbr|truncatechars_html:25 }} {% if user.userprofileinfo.verified %} <span class="image-profile-verified"><img draggable="false" title="Verified User" class="verifed" src="{% static 'images\verified.png' %}" alt="verified" width="25" height="25" srcset=""></span> {% endif %}</h2>
<p>{{ user.first_name }} {{ user.last_name }}</p><br>
</div>
</div>
<div class="profile-page-user-desc-box">
<p>{{ user.userprofileinfo.description }}</p>
<p>{{ user.userprofileinfo.website }}</p>
<p>{{ user.userprofileinfo.joined_date |date:"F d Y" }}</p>
</div>
<br>
{% if user.userprofileinfo.image %}
<img class="rounded-circle account-img" src="{{ user.userprofileinfo.image.url }}" alt="{{ user }}'s Profile Picture'">
{% endif %}
</div>
<div class="user-post-user-profile-page">
<h1 title="{{ user }}">Posts</h1>
{% for post in posts %}
<div class="content">
<div class="post">
<h1 class='posttitle'>{{ post.title }}</h1>
<img class="user-image" src="{{ post.author.userprofileinfo.image.url }}" alt="pfp" width="20%" height="20%">
{% if post.published_date %}
<!-- <div class="postdate">
<i class="fas fa-calendar-day"></i> <p>Posted {{ post.published_date|timesince }} ago</p>
</div> -->
<div class="posted-by">
<p>Posted by <strong>{{ post.author }}</strong> {{ post.published_date|timesince }} ago</p>
</div>
{% else %}
<a class="pub-post" href="{% url 'mainapp:post_publish' pk=post.pk %}">Publish</a>
{% endif %}
<p class='postcontent' >{{ post.text|safe|linebreaksbr }}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
And here is the user_posts page
{% block content %}
<div class="sidebar">
<p class="active" href="#">{{ view.kwargs.username }}</p>
<button class="commentbtn"><a class="aclass" href="#">Connect with {{ view.kwargs.username }}</a></button>
<p>{{ user.userprofileinfo.email }}</p>
<p>Lorem</p>
</div>
{% for post in posts %}
<div class="content">
<div class="post">
<h1 class='posttitle'>{{ post.title }}</h1>
<img class="user-image" src="{{ post.author.userprofileinfo.image.url }}" alt="pfp" width="20%" height="20%">
{% if post.published_date %}
<!-- <div class="postdate">
<i class="fas fa-calendar-day"></i> <p>Posted {{ post.published_date|timesince }} ago</p>
</div> -->
<div class="posted-by">
<p>Posted by <strong>{{ post.author }}</strong> {{ post.published_date|timesince }} ago</p>
</div>
{% else %}
<a class="pub-post" href="{% url 'mainapp:post_publish' pk=post.pk %}">Publish</a>
{% endif %}
<p class='postcontent' >{{ post.text|safe|linebreaksbr }}</p>
</div>
</div>
{% endfor %}
{% endblock %}
I have tried to merge the FBV into the CBV by cutting it and pasting it below the get_queryset method So like this
def get_queryset(self):
#... code here
def view_profile(request,pk=None):
#... code here
However this did not work. I am just curious as to how I can integrate both together so I can have the best of both worlds in one place
EDIT: Here are the models
class UserProfileInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,max_length=30)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
description = models.CharField(max_length=150)
website = models.URLField(max_length=200)
image = ProcessedImageField(upload_to='profile_pics',
processors=[ResizeToFill(150, 150)],
default='default.jpg',
format='JPEG',
options={'quality': 60})
joined_date = models.DateTimeField(blank=True,null=True,default=timezone.now)
verified = models.BooleanField(default=False)
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
and now the post
class Post(models.Model):
author = models.ForeignKey(User,related_name='posts',on_delete=models.CASCADE)
title = models.CharField(max_length=75)
text = models.TextField()
group = models.ForeignKey(Group,null=True,blank=True,related_name='posts',on_delete=models.CASCADE)
created_date = models.DateTimeField(default=timezone.now)
image = models.ImageField(upload_to='post_images',blank=True,null=True)
file = models.FileField(upload_to='post_files',blank=True,null=True)
published_date = models.DateTimeField(blank=True,null=True,auto_now_add=True)
comments_disabled = models.BooleanField(default=False)
NSFW = models.BooleanField(default=False)
spoiler = models.BooleanField(default=False)
tags = TaggableManager()
def __str__(self):
return self.title
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
Also in continuation to Ian answer, if you have a direct relationship between models then you can simply get the posts for the particular user like this:
def view_profile(request,pk=None):
if pk:
user_profile = User.objects.get(pk=pk)
user_posts = Posts.objects.filter(user__id=pk) #<---add these
else:
user_profile = request.user
user_posts = Posts.objects.filter(user__id = request.user.id) #<---add these
context = {
'user':user_profile,
'user_posts':user_posts
}
return render(request,'mainapp/profile.html',context)
A simple class based view for getting a user:
class UserDetailView(DetailView):
model = User
template_name = 'mainapp/profile.html'
context_object_name = 'user'
Relationships (foreign keys) can be followed backwards. Every foreign key has a reverse relationship defined (unless you set reverse_name to +...) it will usually be named <modelname>_set on the model referenced by the foreign key
For example, the following two lines are equivalent
Post.objects.filter(author=user)
user.post_set.all()
This can be used in your profile template
{% for post in user.post_set.all %}
...
{% endfor %}
I'm using flask. Database is sqlite3.
In short. I can make lists and I can tick them off as "finished", I want to show the numbers of finished lists in the users profile.
At this time it shows the same as "all lists"..
This is my List model:
class List(Model):
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model=User,
related_name='list'
)
content = TextField()
finished = BooleanField(default=False)
class Meta:
database = DATABASE
order_by = ('-timestamp',)
This is my find finished lists function on the User model:
def finished_lists(self):
return List.select().where(
(List.user == self) |
(List.finished == True)
)
This is the profile template:
{% extends "stream.html" %}
{% block content %}
<div class="row">
<div class="">
<h1>{{ user.username }}</h1>
</div>
<div class="">
<div class="">
<h5>Followers</h5>
<p>{{ user.followers().count() }}</p>
</div>
<div class="">
<h5>Following</h5>
<p>{{ user.following().count() }}</p>
</div>
<div class="">
<h5>Lists</h5>
<p>{{ user.list.count() }}</p>
</div>
<div class="">
<h5>Finished</h5>
<p>{{ user.finished_lists().count() }}</p>
</div>
</div>
<div class="grid-25">
{% if current_user.is_authenticated %}
{% if user != current_user %}
{% if not user in current_user.following() %}
Follow
{% else %}
Unfollow
{% endif %}
{% endif %}
{% endif %}
</div>
</div>
{{ super() }}
{% endblock %}
In your finished list function you select all lists corresponding to the user OR (|) finished . Both conditions should be true to select finished lists so you need and (&)