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 %}
Related
I recently started learning Django and can't solve one problem. I created my validator for the form, but instead of showing an error window, it just resets the form.
Here is the code models.py:
from django.db import models
from django.urls import reverse_lazy
from django.core.exceptions import ValidationError
class News(models.Model):
title = models.CharField(max_length=150, verbose_name='Title')
content = models.TextField(blank=True, verbose_name='Content')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Date of publication')
updated_at = models.DateTimeField(auto_now=True, verbose_name='Update')
photo = models.ImageField(upload_to='photos/%Y%m/%d/', verbose_name='Photo', blank=True)
is_published = models.BooleanField(default=True, verbose_name='Is_published ')
category = models.ForeignKey('Category', on_delete=models.PROTECT, null=True, verbose_name='Category')
def get_absolute_url(self):
return reverse_lazy('read', kwargs={'news_id' : self.pk})
def __str__(self):
return self.title
class Meta:
verbose_name = 'new'
verbose_name_plural = 'news'
ordering = ['-created_at', 'title']
class Category(models.Model):
title = models.CharField(max_length=150, db_index=True, verbose_name='Title of category')
def get_absolute_url(self):
return reverse_lazy('category', kwargs={'pk' : self.pk})
def __str__(self):
return self.title
class Meta:
verbose_name = 'category'
verbose_name_plural = 'categories'
ordering = ['-title']
This is the code forms.py:
from django import forms
from .models import News, Category
from django.core.exceptions import ValidationError
import re
class NewsForm(forms.Form):
title = forms.CharField(max_length=150, min_length=1, label='Title', widget=forms.TextInput(attrs={'class' : 'form-control'}))
content = forms.CharField(label='Text', required=False, widget=forms.Textarea(attrs={'class' : 'form-control', 'rows' : 15}))
# photo = forms.ImageField(upload_to='photos/%Y%m/%d/')
is_published = forms.BooleanField(label="To publish", initial=True)
category = forms.ModelChoiceField(label='Category', queryset=Category.objects.all(), empty_label='Select a category', widget=forms.Select(attrs={'class' : 'form-control'}))
def clean_title(self):
raise ValidationError('Error!')
# class NewsForm(forms.ModelForm):
# class Meta:
# model = News
# fields = ['title', 'content', 'is_published', 'category']
# widgets = {
# 'title' : forms.TextInput(attrs={'class' : 'form-control'}),
# 'content' : forms.Textarea(attrs={'class' : 'form-control', 'rows' : 15}),
# 'category' : forms.Select(attrs={'class' : 'form-control'})
# }
And here is the code views.py:
from django.shortcuts import render, get_object_or_404, redirect
from .models import News, Category
from .forms import NewsForm
def news(request):
news = News.objects.all()
return render(request, 'news/news.html', {'news': news, 'title': 'List of news:'})
def get_category(request, pk):
news = News.objects.filter(category_id=pk)
return render(request, 'news/category.html',
{'news': news, 'title': f'List of news in the {str(Category.objects.get(pk=pk))} category :'})
def view_news(request, news_id):
back = request.GET.get('back')
new = get_object_or_404(News, pk=news_id)
return render(request, 'news/read_news.html', {'new' : new, 'back' : back})
def add_news(request):
if request.method == 'POST':
form = NewsForm(request.POST)
if form.is_valid():
new = News.objects.create(**form.cleaned_data)
# new = form.save()
return redirect(str(new.get_absolute_url())+'?back=False')
return render(request, 'news/add_news.html', {'form' : NewsForm() })
Here is the code urls.py:
from django.urls import path
from .views import *
urlpatterns = [
path('news/', news, name='news_all'),
path('news/category/<int:pk>/', get_category, name='category'),
path('news/read/<int:news_id>/', view_news, name='read'),
path('news/add-news/', add_news, name='add'),
]
Code news_tags.py:
from django import template
from ..models import Category
register = template.Library()
#register.simple_tag(name='g_cat')
def get_categories():
return Category.objects.all()
#register.inclusion_tag('news/tags/news_tag.html', name='news_tag')
def news_tag(news, link=False):
return {'news' : news, 'link' : link}
Code news_tag.html:
<div class="col-md-9">
{% for item in news %}
<div class="card mb-3">
<div class="card-header">
{% if link %}
Category: {{ item.category.title }}
{% else %}
Category: {{ item.category.title }}
{% endif %}
</div>
<div class="card-body">
<div>
{% if item.photo %}
<img src="{{ item.photo.url }}" alt="" class="news-media-photo">
{% endif %}
<div class="media-body">
<h5 class="card-title" style="color: {% cycle 'red' 'green' %}">{{ forloop.revcounter }}. {{ item.title }}</h5>
<p class="card-text">{{ item.content|linebreaks|truncatewords:50 }}</p>
Читать дальше...
</div>
</div>
</div>
<div class="card-footer text-muted">
{{ item.created_at|timesince }} назад...
</div>
</div>
{% empty %}
<h2>Ooops...</h2>
{% endfor %}
</div>
Here is the code base.html:
<!doctype html>
{% load static %}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<title>{% block title %}News:{% endblock %}</title>
</head>
<body>
{% block navbar %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a class="nav-link" href="{% url 'news_all' %}">Главная</a></li>
<li class="nav-item"><a class="nav-link" href="{% url 'add' %}">Add new</a></li>
</ul>
</div>
</nav>
{% endblock %}
<div class="container mt-3">
<h2>{% block list_title %}News:{% endblock %}</h2>
<div class="row">
{% block sidebar %}
<div class="col-md-3">
{% load news_tags %}
<div class="list-group">
{% g_cat as g_cat %}
Все
{% for i in g_cat %}
<a href="{{ i.get_absolute_url }}" class="list-group-item list-group-item-action">
{{ i.title }}
</a>
{% endfor %}
</div>
</div>
{% endblock %}
{% block content %}
{% endblock %}
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.14.6/dist/umd/popper.min.js"
integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
crossorigin="anonymous"></script>
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
</body>
</html>
Here is the code add_news.html:
{% extends 'base.html' %}
{% block title %}Add new{% endblock %}
{% block list_title %}
<p align="center">{{ new.title }}</p>
{% endblock %}
{% block navbar %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a class="nav-link" href="{% url 'news_all' %}">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#" onclick="history.back();return false;">Cancel</a></li>
</ul>
</div>
</nav>
{% endblock %}
{% block sidebar %}{% endblock %}
{% block content %}
<div class="col-md-12">
<h1>Add new</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
{% comment %}
{{ form.non_field.errors }}
{% for i in form %}
<div class="form-group">
{{ i.label_tag }}
{{ i }}
<div class="invalid-feedback">
{{ i.errors }}
</div>
</div>
{% endfor %}
{{ form.non_field.errors }}
<div class="form-group">
<label for="{{ form.title.id_for_label }}">Title</label>
{{ form.title }}
<div class="invalid-feedback">
{{ form.title.errors }}
</div>
</div>
<div class="form-group">
<label for="{{ form.content.id_for_label }}">Text</label>
{{ form.content }}
<div class="invalid-feedback">
{{ form.content.errors }}
</div>
</div>
<div class="form-group">
<label for="{{ form.is_published.id_for_label }}">To publish</label>
{{ form.is_published }}
<div class="invalid-feedback">
{{ form.is_published.errors }}
</div>
</div>
<div class="form-group">
<label for="{{ form.category.id_for_label }}">Category</label>
{{ form.category }}
<div class="invalid-feedback">
{{ form.category.errors }}
</div>
</div>
{% endcomment %}
<button type="submit" class="btn btn-primary btn-block">Add new</button>
</form>
</div>
{% endblock %}
Code read_news.html:
{% extends 'base.html' %}
{% block title %}Новость - {{ new.title }}{% endblock %}
{% block list_title %}
<p align="center">{{ new.title }}</p>
{% endblock %}
{% block navbar %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="/">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item"><a class="nav-link" href="{% url 'news_all' %}">Главная</a></li>
{%if back is None %}
<li class="nav-item"><a class="nav-link" href="#" onclick="history.back();return false;">Back</a></li>
{% elif back == False %}
<li class="nav-item"><a class="nav-link" href="/news/news/">Back</a></li>
{% endif %}
</ul>
</div>
</nav>
{% endblock %}
{% block sidebar %}{% endblock %}
{% block content %}
<div class="col-md-12">
<div class="card mb-3">
<div class="card-header">
Category: {{ new.category.title }}
</div>
<div class="card-body">
<div>
{% if new.photo %}
<img src="{{ new.photo.url }}" alt="" height="250" class="news-media-photo">
{% endif %}
<div class="media-body">
<p class="card-text">{{ new.content|linebreaks }}</p>
</div>
</div>
</div>
<div class="card-footer text-muted">
{{ new.created_at|timesince }} ago...
</div>
</div>
</div>
{% endblock %}
Here is the code news.html:
{% extends 'base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block list_title %}
{{ title }}
{% endblock %}
{% block content %}
{% load news_tags %}
{% news_tag news True %}
{% endblock %}
Here is the code category.html:
{% extends 'base.html' %}
{% block title %}
{{ title }}
{% endblock %}
{% block list_title %}
{{ title }}
{% endblock %}
{% block content %}
{% load news_tags %}
{% news_tag news %}
{% endblock %}
For displaying custom error messages, you have to disable the default behavior of html5 of required field, you can use novalidate in the form.
You can also show particular field error messages in loop.
Try this code:
add_news.html
<div class="col-md-12">
<h1>Add new</h1>
<form method="POST" novalidate>
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{error|striptags}}
{% endfor %}
{% endif %}
{% for field in form %}
<div class="form-group">
{{ field.label_tag }}
{{field}}
<div class="invalid-feedback">
{% for error in field.errors %}
{{error}}
{% endfor %}
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary btn-block">Add new</button>
</form>
</div>
I have implemented search bar functionality with autocomplete feature. All is good except the fact that in HTML serach results contain multiple the same object. For instance, when I put 2 in my searchbar I see 4 the same in my HTML file. What I want is to get unique objects.
views.py
#login_required
def search_address_qa(request):
query = request.GET.get('title')
payload = []
if query:
lookups = Q(title__icontains=query)
address_objects = Article.objects.filter(lookups)
address_objects_qa = QA.objects.filter(lookups)
for address_object in address_objects or address_objects_qa:
payload.append(address_object.title)
return JsonResponse({'status':200, 'data': payload})
#login_required
def search_articles(request):
query = request.GET.get('q')
article = Article.objects.filter(title__icontains=query)
qa_list = QA.objects.filter(title__icontains=query)
if query is not None:
lookups = Q(title__icontains=query) | Q(tags__name__icontains=query)
article = Article.objects.filter(lookups)
qa_list = QA.objects.filter(lookups)
context = {
'search_articles': article,
'query_name': query,
'qa_list': qa_list
}
return render(request, 'search/search_articles.html', context)
search_view.html
{% extends 'base.html' %}
<title>{% block title %}search results{% endblock %}</title>
{% block search %}
{% include 'main/sidebar.html'%}
<link rel="stylesheet" type="text/css" href="/static/search.css">
<div class="d-flex justify-content-end h-100 pb-4">
<div>
{% if user.is_authenticated %}
<form action="{% url 'search_articles' %}" method="get" id="search">
{% csrf_token %}
<div class="searchbar " id="autocomplete">
<input name="q" type="text" placeholder="Search articles" class="search_input">
<i class="fas fa-search"></i>
<ul class="autocomplete-result-list"></ul>
</div>
</form>
{% endif %}</div>
</div>
{% endblock search %}
{% block content %}
<div class="d-flex justify-content-start pb-4">Search results for my question: <div class="ml-1 fw-bold"> {{ query_name }} </div></div>
<div class="container-fluid pb-4">
<h4>Articles</h4>
<hr>
<div class="row row-flex row-cols-1 row-cols-md-3 g-4">
{% for article in search_articles %}
<div class="col-lg-3 d-flex align-items-stretch">
<a href="{{ article.get_absolute_url }}">
<div class="card h-100 shadow text-left">
<h5 class="card-header">{{article.title}}</h5>
<img src="/static/preview_homepage3.png" class="card-img-top">
<div class="card-body">
<h5 class="card-title">{{ article.slug }}</h5>
<p class="card-text">
{% comment %} {% lorem 10 w %} {% endcomment %}
{{article.body | safe | truncatechars:75}}
</p>
</a><br>
{% include 'main/tag_cards.html' %}
</div>
<div class="card-footer">
<small class="text-muted">{{ article.publish|date:"d F Y" }}</small>
</div>
</div>
</div>
{% empty %}
<div class="container d-flex justify-content-center">No results</div>
{% endfor %}
</div>
</div>
<h4>Related questions</h4>
<hr>
<div class="container h-100 py-2 mb-4">
{% for qa in qa_list %}
<div class="card text-dark bg-light mb-3 text-left">
<a href="{{ qa.get_absolute_url }}">
<h5 class="card-header">Q: {{qa.title}}</h5>
<div class="card-body">
<div class="card-title text-justify">A: {{ qa.answer |safe | striptags }}</div>
{% comment %} <p class="card-text"> {{ qa.author }}</p> {% endcomment %}
</div>
<div class="card-footer">
<small class="text-muted">Published: {{qa.publish}}</small>
</div>
</a>
</div>
{% empty %}
<p>No results</p>
{% endfor %}
{% endblock %}
You can make use of Django's distinct() QuerySet method
.disctinct() Returns a new QuerySet that uses SELECT DISTINCT in its SQL query. This eliminates duplicate rows from the query results.
Change
article = Article.objects.filter(lookups)
to
article = Article.objects.filter(lookups).distinct()
Why does it happen?
In your case, this happens because you are using the Q object,
lookups = Q(title__icontains=query) | Q(tags__name__icontains=query)
suppose your search text is "test" and you have a row in the table with title="text" and tag_name="text", then the lookup will match both title and tag which leads to generating duplicate rows (since you are performing an OR operation in your lookkups) with the same result.
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 am having some trouble getting a drilldown for mptt in my template.
I have the following model.
models.py
class Dimension_value(MPTTModel):
name = models.CharField(max_length = 200, null=True, blank = True, default = '')
parent = TreeForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, related_name="children")
class MPTTMeta:
order_insertion_by = ['name']
def __str__(self):
return self.name
views.py
def show_dimensions(request):
return render(request, "accounts/dimension_detail.html", {'dimensions': Dimension_value.objects.all()})
template.py
{% extends 'base.html' %}
{% block head %}
{% endblock %}
{%block body%}
<div class="container-fluid">
<div class="card">
<div class="card-body">
<h2>My dimensions</h2>
{% load mptt_tags %}
{% drilldown_tree_for_node dimensions as drilldown cumulative count accounts.Dimension_value.name in game_count %}
{% for node,structure in drilldown|tree_info %}
{% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
{% if node == dimension %}
<strong>{{ node.name }}</strong>
{% else %}
{{ node.name }}
{% if node.parent_id == dimension.pk %}({{ node.game_count }}){% endif %}
{% endif %}
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
{% endfor %}
</div>
</div>
<br>
<br>
<a class="btn btn-primary" href="{% url 'add_plan' %}" role="button">Add a plan</a>
<button onclick="goBack()" class = "btn btn-secondary">Go Back</button><br><br><a class="btn btn-primary" href="{% url 'subscribeusertoplan' %}" role="button">Add a user to plan</a>
</div>
{%endblock%}
I have added the view according to the documentation found here: https://django-mptt.readthedocs.io/en/latest/templates.html?highlight=examples#examples
However I get the following error.
Exception Type: AttributeError
Exception Value:
'TreeQuerySet' object has no attribute '_tree_manager'
Hope someone can nudge me in the right direction. Thanks!
You can do this by using some css and jquery
{% block head %}
{% endblock %}
{%block body%}
<div class="container-fluid">
<div class="card">
<div class="card-body">
<h2>My dimensions</h2>
{% load mptt_tags %}
{% recursetree dimensions %}
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{node.level}}" aria-expanded="false" aria-controls="collapsed">
{{ node.name }}</a>
{% if not node.is_leaf_node %}
<ul class="children">
<div id="collapse{{node.level}}" class="children panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
{{ children }} </div>
</div>
</ul>
{% endif %}
{% endrecursetree %}
</div>
</div>
<br>
<a class="btn btn-primary" href="{% url 'add_plan' %}" role="button">Add a plan</a>
<button onclick="goBack()" class = "btn btn-secondary">Go Back</button><br><br><a class="btn btn-primary" href="{% url 'subscribeusertoplan' %}" role="button">Add a user to plan</a>
</div>
{%endblock%}
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 %}