It is returning an error : Not Found: /post-detail/6/images/wallpaper002.jpg. I have tried to show image through {{ post_detail.img.all.first.url }} but I could show image in the template, it returns None value.
news.html
'''
<div class="text-center">
<img class="detail_picture img-thumbnail" src="{{ post_detail.img.all.first }}">
</div>
'''
models.py
'''
class Pictures(TimestampedModel):
img = models.ImageField(upload_to='images')
def __str__(self):
return str(self.img)
class Post(TimestampedModel):
title = models.CharField(max_length=128)
lang = models.IntegerField(choices=LANGUAGES, default=1)
short_description = models.CharField(max_length=255, blank=True, null=True)
description = models.TextField(blank=True, null=True)
category = models.ManyToManyField(PostCategoies, blank=True)
img = models.ManyToManyField(Pictures, blank=True)
icon = models.CharField(max_length=128, blank=True, null=True, help_text="Example: fa fa-info")
is_active = models.BooleanField(default=True)
def __str__(self):
return self.title
'''
views.py
'''
from django.shortcuts import render, redirect
from django.contrib import messages
from django.views import View
from .models import Post, Pictures
from django.views.generic import DetailView
from . import models
from django.shortcuts import get_object_or_404
class HomePageView(View):
def get(self, request):
posts = Post.objects.all()[:4]
context = {'posts': posts}
return render(request, 'index.html', context)
class PostDetailView(DetailView):
context_object_name = "post_detail"
model = models.Post
template_name = 'news.html'
'''
urls.py
'''
app_name = 'posts'
urlpatterns = [
path('', HomePageView.as_view(), name=""),
path('post-detail/<int:pk>/', PostDetailView.as_view(), name="post_detail")
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
'''
You are accessing the instance of a Pictures class with your current code. You need to then access the img property:
<div class="text-center">
<img class="detail_picture img-thumbnail" src="{{ post_detail.img.all.first.img.url }}">
</div>
I would also suggest that you protect against the case of not having an instance in the ManyToMany field
{% if post_detail.img.all.first %}
<div class="text-center">
<img class="detail_picture img-thumbnail" src="{{ post_detail.img.all.first.img.url }}">
</div>
{% endif %}
I'd also suggest looking into prefetch_related and/or Subquery as a way to more efficiently fetch these related details. It will help you prevent N+1 queries. You can verify you're not running too many queries with the django debug toolbar.
Related
In this program i have these two functions in my views.py:
def home(request):
p=product.objects.all()
return render(request,'home.html',{'p':p})
def foods(request):
p=product.objects.all()
return render(request,'foods.html',{'p':p})
They both have access to the same data from database i mean if i want to post some json with django restframework then foods and home will have the same data because they have the same html:
<div class="grid">
{% for i in p%}
<div class='card'>
<img src="{{i.image}}"></img>
<p id="id">{{i.description}}</p>
<a href="{{i.buy}}" target='_blank' rel='noopener noreferrer'>
<button><span class="price"> ${{i.price}}</span> buy</button>
</a>
</div>
{%endfor%}
</div>
it is good for me to have just one html for multiple pages and then access to different data from database but if i add some json both of them will contain the same data(for some reason data of foods is empty but it will generate the same number of products based on json like home)
I want to know how can you have same html for multiple categories or pages and then add specific or different data from database to them?
More details:
models.py:
from django.db import models
# Create your models here.
class product(models.Model):
image=models.CharField(max_length=500)
description=models.CharField(max_length=500)
price=models.CharField(max_length=50)
buy=models.CharField(max_length=100)
serializers.py:
from rest_framework import serializers
from .models import product
class productSerializer(serializers.ModelSerializer):
class Meta:
model= product
fields="__all__"
views.py:
from django.shortcuts import render
from .models import *
from rest_framework import viewsets,status
from .serializers import productSerializer
from rest_framework.parsers import JSONParser
from django.http import HttpResponse,JsonResponse
from rest_framework.response import Response
from rest_framework.decorators import action
class productviewset(viewsets.ModelViewSet):
queryset=product.objects.all()
serializer_class = productSerializer
def create(self, request):
serialized = productSerializer(data=request.data, many=True)
if serialized.is_valid():
serialized.save()
return Response(serialized.data, status=status.HTTP_201_CREATED)
return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)
#action (detail=False , methods=['post'])
def delete(self,request):
product.objects.all().delete()
return Response('success')
def home(request):
p=product.objects.all()
return render(request,'home.html',{'p':p})
def foods(request):
p=product.objects.all()
return render(request,'foods.html',{'p':p})
If i have 20 categories with 20 different pages i will never create 20 different databases if there is a way for those categories to access specifically from the same database.
If I understand the question correctly and you will have a certain amount of goods divided into 20 categories, then I somehow used this
You need to create a separate model for the categories, and in the product model add a foreign key to the category
models.py
class Category(models.Model):
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=True)
def get_absolute_url(self):
return reverse('shop:product_list_by_category',
args=[self.slug])
def __str__(self):
return self.name
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products')
available = models.BooleanField(default=True)
...
views.py
def product_list(request, category_slug=None):
category = None
categories = Category.objects.all()
products = Product.objects.filter(available=True)
if category_slug:
category = get_object_or_404(Category, slug=category_slug)
products = products.filter(category=category)
return render(request,
'shop/product/list.html',
{'category': category,
'categories': categories,
'products': products})
urls.py
from django.urls import path
from . import views
app_name = 'shop'
urlpatterns = [
path('', views.product_list, name='product_list'),
path('<category_slug>', views.product_list, name='product_list_by_category'),
]
html
{% block content %}
<div id="main" class="product-list">
<h1>{% if category %}{{ category.name }}{% else %}Products{% endif %}</h1>
{% for product in products %}
<div class="item">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
</div>
{% endfor %}
</div>
{% endblock %}
I'm trying to display a group of images classified by category. When the user clicks on a category name, the page should display the images that belongs to that category. I'm getting the the next browser error:
NoReverseMatch at /services/
'services' is not a registered namespace
. . .
Error during template rendering
The models belongs to different apps, one (that contains the Category model) works fine, and this other (That contains the Services model) just works if I delete the html content that I need. Help me please.
Here are my files:
home_app/models.py
from django.db import models
from django.urls import reverse
class Category(models.Model):
name=models.CharField(primary_key=True, max_length=50)
slug=models.SlugField(unique=True, blank=True, null=True)
image=models.ImageField(upload_to='category_home')
description=models.CharField(max_length=100)
content=models.TextField(max_length=500, default="Service")
created=models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Category'
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('services:services_by_category', args=[self.slug])
services_app/models.py
from django.db import models
from home_app.models import Category
class Services(models.Model):
category=models.ForeignKey(Category, on_delete=models.CASCADE)
title=models.CharField(max_length=50)
completed=models.DateField(auto_now_add=False, null=True, blank=True)
content=models.CharField(max_length=50, null=True, blank=True)
image=models.ImageField(upload_to='services_services')
created=models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Service'
verbose_name_plural = 'Services'
def __str__(self):
return '%s de %s' % (self.category, self.title)
services_app/views.py
from django.shortcuts import render, get_object_or_404
from .models import Services
from home_app.models import Category
def service_list(request,category_slug=None):
category = None
categories = Category.objects.all()
services = Services.objects.all()
if category_slug:
category = get_object_or_404(Category,slug=category_slug)
services = services.filter(category=category)
return render(request, 'services_app/services.html', {'categories':categories, 'category':category, 'services':services,})
services_app/urls.py
from django.urls import path
from services_app import views
urlpatterns = [
path('', views.service_list, name='Services'),
path('<slug:category_slug>', views.service_list, name='services_by_category'),
]
services_app/templates/services_app/services.html
{% extends "home_app/base.html" %}
{% load static %}
{% block content %}
<!-- The app only works if I delete this section -->
<div id="sidebar">
<h3>Categories</h3>
<ul>
{% for c in categories %}
<li>
<h4>{{ c.name }}</h4>
</li>
{% endfor %}
</ul>
</div><br>
<div>
<h1>{% if category %}{{ category.name }}{% endif %}</h1>
{% for service in services %}
<img src="{{service.image.url}}">
{% endfor %}
</div>
{% endblock %}
Also my main urls:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('home_app.urls')),
path('services/', include('services_app.urls')),
path('contact/', include('contact_app.urls')),
]
Just change en models.py the following:
def get_absolute_url(self):
return reverse('services_by_category', args=[self.slug])
'cause you have not defined the namespace services.
I'm learning how to use urls in Django and I have a problem. I'm trying to get all services that belongs to a category by clicking on the category link, but when I do that, the browser returns me this error:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/services/None
Raised by: services_app.views.service_list
No Category matches the given query.
And the url looks:
http://localhost:8000/services/None
I already have a populated data base, and it can display their content just using a djanfo for, but I need it to be displayed by categories. Can anyone help me?
Here are my files:
home_app/models.py
from django.db import models
from django.urls import reverse
class Category(models.Model):
name=models.CharField(primary_key=True, max_length=50)
slug=models.SlugField(unique=True, blank=True, null=True)
image=models.ImageField(upload_to='category_home')
description=models.CharField(max_length=100)
content=models.TextField(max_length=500, default="Service")
created=models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Category'
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('services_by_category', args=[self.slug])
services_app/models.py
from django.db import models
from home_app.models import Category
class Services(models.Model):
category=models.ForeignKey(Category, on_delete=models.CASCADE)
title=models.CharField(max_length=50)
completed=models.DateField(auto_now_add=False, null=True, blank=True)
content=models.CharField(max_length=50, null=True, blank=True)
image=models.ImageField(upload_to='services_services')
created=models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Service'
verbose_name_plural = 'Services'
def __str__(self):
return '%s de %s' % (self.category, self.title)
services_app/views.py
from django.shortcuts import render, get_object_or_404
from .models import Services
from home_app.models import Category
def service_list(request,category_slug=None):
category = None
categories = Category.objects.all()
services = Services.objects.all()
if category_slug:
category = get_object_or_404(Category,slug=category_slug)
services = services.filter(category=category)
return render(request, 'services_app/services.html', {'categories':categories, 'category':category, 'services':services,})
services_app/urls.py
from django.urls import path
from services_app import views
urlpatterns = [
path('', views.service_list, name='Services'),
path('<slug:category_slug>', views.service_list, name='services_by_category'),
]
services_app/templates/services_app/services.html
{% extends "home_app/base.html" %}
{% load static %}
{% block content %}
<div id="sidebar">
<br>
<br>
<h3>Categories</h3>
<ul>
{% for c in categories %}
<li>
<h4>{{ c.name }}</h4>
</li>
{% endfor %}
</ul>
</div><br>
<div>
<h1>{% if category %}{{ category.name }}{% endif %}</h1>
{% for service in services %}
<img src="{{service.image.url}}">
{% endfor %}
</div>
{% endblock %}
Also my main urls:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('home_app.urls')),
path('services/', include('services_app.urls')),
path('contact/', include('contact_app.urls')),
]
The problem is you don' t generate the slug of Category:
from django.db import models
from django.urls import reverse
from django.utils.text import slugify
class Category(models.Model):
name=models.CharField(primary_key=True, max_length=50)
slug=models.SlugField(unique=True, blank=True, null=True)
image=models.ImageField(upload_to='category_home')
description=models.CharField(max_length=100)
content=models.TextField(max_length=500, default="Service")
created=models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = 'Category'
verbose_name_plural = 'Categories'
def save(self, *args, **kwargs):
if self._state.adding:
self.slug = slugify(self.name)
super().save(*args, **kwargs)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('services_by_category', args=[self.slug])
Note that you need to set manually the slug of the
existing Category instances (with the admin, a shell or a migration), or you can simply recreate them.
I'm pretty new to Django and already have read a lot about class-based views before coming here. I'm trying to build a one page website, with dynamic blocks that can be written from the Django admin. My problem is that I cannot manage to render variables from my database in my template. Here's what I wrote:
models.py
from django.db import models
from tinymce.models import HTMLField
class MyResume(models.Model):
subline = models.CharField(max_length=200)
content = HTMLField()
class Meta:
verbose_name = "My Resume"
verbose_name_plural = "My Resume"
def __str__(self):
return "My Resume"
class AboutMe(models.Model):
subline = models.CharField(max_length=200)
content = HTMLField()
cover_img = models.ImageField(upload_to="about_me")
class Meta:
verbose_name = "About me"
verbose_name_plural = "About me"
def __str__(self):
return "About me"
class Experience(models.Model):
subline = models.CharField(max_length=200)
pres_content = models.TextField()
exp_content = HTMLField()
date_exp = models.IntegerField()
class Meta:
verbose_name = "Experience"
verbose_name_plural = "Experiences"
def __str__(self):
return "Experience"
class ProjectPost(models.Model):
title = models.CharField(max_length=200)
technology = models.CharField(max_length=100)
subline = models.CharField(max_length=200)
content = HTMLField()
project_post_cover = models.ImageField(upload_to="projectpost_cover")
class Meta:
verbose_name = "Project Post"
verbose_name_plural = "Project Posts"
def __str__(self):
return self.title
class BlogPost(models.Model):
title = models.CharField(max_length=200)
overview = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
content = HTMLField()
blogpost_thumbnail = models.ImageField(upload_to="blogpost_thumbnail")
class Meta:
verbose_name = "Blog Post"
verbose_name_plural = "Blog Posts"
def __str__(self):
return self.title
class Contact(models.Model):
subline = models.CharField(max_length=200)
presentation_content = HTMLField()
def __str__(self):
return "Contact section text"
views.py
from django.shortcuts import render
from django.views.generic.base import TemplateView
from .models import *
class IndexTemplateView(TemplateView):
template_name = 'index.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) # first, call super get context data
context['myresume'] = MyResume.objects.all()
context['aboutme'] = AboutMe.objects.all()
context['experience'] = Experience.objects.all()
context['projectpost'] = ProjectPost.objects.all()
context['blogpost'] = BlogPost.objects.all()
context['contact'] = Contact.objects.all()
return context
core.urls.py:
from django.urls import path
from .views import IndexTemplateView
urlpatterns = [
path('', IndexTemplateView.as_view()),
]
appname.urls.py:
from django.contrib import admin
from django.urls import include, path
from django.conf.urls import url
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^tinymce/', include('tinymce.urls')),
path('', include('core.urls')),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
and a snippet from my index.html template:
{% extends 'base.html' %}
{% load static %}
{% block content %}
(...)
<!-- ==================== ABOUT ==================== -->
<section id="about" class="section">
<h2 class="title">ABOUT</h2>
<div class="section-des">
{{ aboutme.subline }}
</div>
<div class="content-670">
<p>
{{ aboutme.content }}
</p>
</div>
<img class="about-img block-right" data-jarallax-element="0 -40" src="{{ aboutme.cover_img.url }}" alt="">
(...)
{% endblock content %}
All of the variables you've added to your template context are querysets, not objects. But you're trying to read them as individual objects in your template, which is why it doesn't work. You have two options:
Iterate over each queryset in your template:
{% for item in aboutme %}
<h2 class="title">ABOUT</h2>
{{ item.subline }}
{{ item.content }}
{% endfor %}
If you only want to display one of each model, then you need to fix your context method to only return one object, e.g.,
context['aboutme'] = AboutMe.objects.first()
Where here you're just returning the first AboutMe object in the database. If you do this, then your existing template logic will work. How you determine which object to return depends on what your data looks like.
{% for obj in myresume %}
<p>{{ obj.subline }}</p>
{% endfor %}
{% for obj in aboutme %}
<p>{{ obj.subline }}</p>
{% endfor %}
you can call your objects in this way in your templates. Also modify str function in models to get the dynamic content.
class MyResume(models.Model):
subline = models.CharField(max_length=200)
content = HTMLField()
class Meta:
verbose_name = "My Resume"
verbose_name_plural = "My Resume"
def __str__(self):
return self.sublime
every one ,,I can upload image from admin site,, but do not know how to upload image from the templates,,
models.py
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
from django.utils import timezone
def get_imagep_Product(instance, filename):
return '/'.join(['products', instance.slug, filename])
class ProductsTbl(models.Model):
model_number = models.CharField(max_length=255, blank=True, null=True)
name = models.CharField(max_length=255, blank=True, null=True)
material = models.TextField(blank=True, null=True)
feature = models.TextField(blank=True, null=True)
created = models.DateTimeField(editable=False)
modified = models.DateTimeField(auto_now=True)
release = models.DateTimeField(blank=True, null=True)
submit_date = models.DateTimeField(blank=True, null=True)
slug = models.SlugField(unique=True)
user = models.ForeignKey(User, blank=True, null=True)
image = models.ImageField(upload_to=get_imagep_Product, blank=True) #image file
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.id:
self.created = timezone.now()
return super(ProductsTbl, self).save(*args, **kwargs)
views.py
from django.shortcuts import render,redirect
from .forms import ProductsTblForm
from .models import ProductsTbl
from django.template.defaultfilters import slugify
from django.contrib.auth.decorators import login_required
from django.http import Http404,HttpResponse
import datetime
def create_thing(request):
form_class = ProductsTblForm
if request.method == 'POST':
form = form_class(request.POST)
if form.is_valid():
thing = form.save(commit=False)
thing.user = request.user
thing.slug = slugify(thing.model_number)
thing.save()
return redirect('thing_detail', slug=thing.slug)
else:
form = form_class()
return render(request, 'things/create_thing.html', { 'form': form,})
urls.py
from django.conf.urls import patterns, url,include
from django.contrib import admin
from django.views.generic import TemplateView
from designer import views
from designer.backends import MyRegistrationView
from django.conf import settings
urlpatterns = [
url(r'^create_thing/$', views.create_thing, name='create_thing'),
]
if settings.DEBUG:
urlpatterns += [
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
]
forms.py
from django.forms import ModelForm
from .models import ProductsTbl
class ProductsTblForm(ModelForm):
class Meta:
model = ProductsTbl
fields = ('model_number','name','feature', 'material','release','image',)
create_thing.html
{% extends 'base.html' %} {% block title %}
Create a Thing - {{ block.super }} {% endblock title %}
{% block content %}
<h1>Create a Thing</h1>
<form role="form" action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock content %}
when I click the create things I can see form here,,however I do not know how can let the image upload
I have looking for this link ,,however I do not know how to let it work in my app,,
First, you will need to add enctype="multipart/form-data" in your <form> definition. As this is required for file uploads.
<form role="form" action="" method="post" enctype="multipart/form-data">
Second, instead of form_class(request.POST) you will need to create form in your view by passing request.FILES too.
form_class(request.POST, request.FILES)