Can someone tell me what I'm doing wrong here? The 1st function(all_products) renders in template perfectly, but the last 2 does not.
models.py
# TABLE BRAND
class Brand(models.Model):
name = models.CharField(max_length = 50)
# TABLE PRODUCT
class Product(models.Model):
title = models.CharField(max_length = 100)
brand = models.ForeignKey(Brand, on_delete = models.CASCADE)
image = models.ImageField(null = False, blank = False, upload_to ="images/",)
price = models.DecimalField(max_digits = 100, decimal_places = 2, )
created = models.DateTimeField(auto_now_add = True )
the functions in the views.py
def all_products(request):
products = Product.objects.all()
return render(request, 'store/home.html', {'products': products})
def newest_products(request):
sixNewestProduct = Product.objects.all().order_by('-created')[:6]
return render(request, 'store/home.html', {'sixNewestProduct': sixNewestProduct})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.all_products, name= 'all_products'),
path('', views.newest_products, name= 'newest_products'),
path('', views.newest_discount, name= 'newest_discount'),
]
the template part look like this:
{% for new in sixNewestProduct %}
<a href="#" class="">
<div class="newProduct">
<img src="{{new.image.url}}" alt="">
</div>
<h5>{{new.brand.name}}</h5>
<h4>{{new.title}}</h4>
<p>{{new.price}} GNF</p>
</a>
{% endfor %}
Need to correct url path like this
from django.urls import path
from . import views
urlpatterns = [
path('', views.all_products, name= 'all_products'),
path('newest_products/', views.newest_products, name= 'newest_products'),
path('newest_discount/', views.newest_discount, name= 'newest_discount'),
]
Django matches the request with the first view it encounters which path matches the current request's path:
from django.urls import path
from . import views
urlpatterns = [
# Django will always match this '' to the view `all_products`
path('', views.all_products, name= 'all_products'),
path('newest_products/', views.newest_products, name= 'newest_products'),
path('newest_discount/', views.newest_discount, name= 'newest_discount'),
]
as #Mahammadhusain kadiwala answer, you'll have to add a different route path for each view
Related
I have spent over three days on this. It appears that something saved to the db, but when I try to access it in the template, I can only get the object of the db. I can not access it. I believe it was not saved successfully because I don't see a media folder where it would be saved. This is what I have so far.
# settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'), )
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# forms.py
from .models import Pic
from django import forms
class ImageForm(forms.ModelForm):
class Meta:
model= Pic
fields= ["picture"]
# models.py
class Pic(models.Model):
picture = models.ImageField(upload_to = 'media/', default = 'media/None/no-img.jpg', null=True, blank= True)
# views.py
def upload(request):
form = ImageForm
context = {}
userBio = Bio.objects.get(userData = User.objects.get(id = request.session['client']['id']))
if request.method == 'POST':
# .is_valid checks the models parameters via forms method
form = ImageForm(request.POST,request.FILES)
if form.is_valid():
form.save()
print("succesful uploaded image")
return redirect("/dashboard")
else:
print("Not a valid input from form....")
messages.error(request,"Not a valid input")
return redirect("/dashboard")
<!-- dashboard.html -->
<form rule="form" class="border border--secondary" method="POST" action="/manageFile" enctype="multipart/form-data">
{% csrf_token%}
<input type="file" name = "update">
<input type = "submit">
</form>
{% if pictures %}
{% for pic in pictures%}
<img src="{{pic}}" alt="{{pic}}">
{% endfor %}
{% endif%}
In the template, it appears as Pic object(1).
In the terminal, it appears as
Query set Pic: Pic object (1)
Here's what I render to the template.
def dash(request):
try:
_id = request.session['client']['id']
except:
return redirect("/loginPg")
userBio = Bio.objects.get(userData = User.objects.get(id = request.session['client']['id']))
print("its right here")
theUploads = Pic.objects.all()
print("This image object -", theUploads)
content = {
"title" : userBio.title,
"qA" : userBio.quoteA,
"qB" : userBio.quoteB,
"desc" : userBio.desc,
"authorA" : userBio.authorA,
"authorB" : userBio.authorB,
"pictures" : theUploads
}
return render(request, "GoEnigma/dashboard.html", content)
# urls.py
from django.conf.urls.static import static
from django.conf import settings
# urls []
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
This was hard to spot, because you render the form field yourself:
class ImageForm(forms.ModelForm):
class Meta:
model= Pic
fields= ["picture"]
<input type="file" name = "update">
So the name of the file field is update, not picture. Change that to picture and it should work, though it's much better to use django to render the form, so you don't mistakes like this and changes to the form get propagated to the html.
If the picture is being saved in the database than the error is with rendering the template. To render the images in template you need to get the {{model_class.model_fields.url}} so in your case the class is pic, the field is picture.
try this in your template <img src="{{pic.picture.url}}">
put parentheses after ImageForm and add request.POST in ImageForm if it is Post request.
def upload:
form = ImageForm()
if request.method == 'POST':
# .is_valid checks the models parameters via forms method
form = ImageForm(request.POST, request.FILES)
if form.is_valid():
form.save()
print("succesful uploaded image")
return redirect("/dashboard")
else:
print("Not a valid input from form....")
messages.error(request,"Not a valid input")
return redirect("/dashboard")
Also check maybe you haven't added url path for serving media files
so add these following lines in urls.py file of main project.
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ..... all regular paths
]
if setting.DEBUG: # if true
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Check official documents here
I wanted to follow the methodology in Python Crash Course Ch. 18 on building the learning_logs app to build the pizzas app. However I'm stuck at displaying the pizzas' name in pizzas.html.
There should be 2 pizzas, named "Hawaiian" and "Meat Lovers". I added both using the admin account. Checked through the shell that both are stored in Pizza.objects.all() so I guess it's the problem to recall them.
Some codes for you all's reference:
views.py:
from django.shortcuts import render
from .models import Pizza
# Create your views here.
def index(request):
""" The home page for Pizzeria. """
return render(request, "pizzas/index.html")
def pizzas(request):
""" Show all pizzas available. """
pizzas = Pizza.objects.all()
content = {"pizza": pizzas}
return render(request, "pizzas/pizzas.html", content)
models.py
from django.db import models
# Create your models here.
class Pizza(models.Model):
""" Pizza available. """
name = models.CharField(max_length = 50)
def __str__(self):
""" Return a string representation of the pizza name. """
return self.name
class Topping(models.Model):
""" The toppoings on the pizza. """
pizza = models.ForeignKey(Pizza, on_delete = models.CASCADE)
text = models.CharField(max_length = 250, unique = True)
def __str__(self):
""" Return a string representation of the toppings. """
return self.text
urls.py:
from django.urls import path, include
from . import views
app_name = "pizzas"
urlpatterns = [
# Home page
path("", views.index, name = "index"),
# Show all pizzas.
path("pizzas/", views.pizzas, name = "pizzas"),
]
pizzas.html:
{% extends 'pizzas/base.html' %}
{% block content %}
<p>Pizzas</p>
<ul>
{% for pizza in pizzas %}
<li>{{ pizza }}</li>
{% empty %}
<li>No pizza duh.</li>
{% endfor %}
</ul>
{% endblock content %}
Expected to see both "Hawaiian" and "Meat Lovers" appears in the list under "Pizzas" in localhost:8000/pizzas.html but instead shows "no pizza duh". What do I miss?
I did see changing the relationship to both models would help solve the problem but if I don't, how can I change the other parts to get what I expect?
You don't have anything called pizzas in your template context; you named the variable pizza.
You should change the context to use pizzas:
content = {"pizzas": pizzas}
I want to use retrained model to classify image by using Django.
In my Django project:
model.py:
from django.db import models
class Image(models.Model):
photo = models.ImageField(null=True, blank=True)
def __str__(self):
return self.photo.name
setttings.py
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'imageupload')
urls.py
from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from imageupload import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index, name='index'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
from django.shortcuts import render
from .form import UploadImageForm
from .models import Image
import os, sys
import tensorflow as tf
def index(request):
if request.method == 'POST':
form = UploadImageForm(request.POST, request.FILES)
if form.is_valid():
picture = Image(photo=request.FILES['image'])
picture.save()
#if os.path.isfile(picture.photo.url):
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
image_path = picture
# Read in the image_data
image_data = tf.gfile.FastGFile(image_path, 'rb').read()
# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line in
tf.gfile.GFile("retrained_labels.txt")]
# Unpersists graph from file
with tf.gfile.FastGFile("retrained_graph.pb", 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def, name='')
with tf.Session() as sess:
# Feed the image_data as input to the graph and get first prediction
softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')
predictions = sess.run(softmax_tensor, {'DecodeJpeg/contents:0': image_data})
# Sort to show labels of first prediction in order of confidence
top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]
a =[]
label = []
for node_id in top_k:
human_string = label_lines[node_id]
score = predictions[0][node_id]
a = [human_string, score]
label.append(a)
return render(request, 'show.html', {'picture':picture, 'label':label})
else:
form = UploadImageForm()
return render(request, 'index.html', {'form': form})
index.html
<p>hello index!</p>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
show.html
<h1>This is show!!</h1>
<img src="{{ picture.photo.url }}" />
<br>
<p>Picture'name is: </p>{{ picture.photo.name }}
<br>
<p>The picture's label:</p>
{{ label }}
<br>
I succeeded in uploading a image later, the browser have the error:
the screenshot of the error
Thank you!!
The question had solved!!This is the change:
image_path = picture.photo.path
and there are two to be change:
1. label_lines = [line.rstrip() for line in tf.gfile.GFile("imageupload/retrained_labels.txt")]
2. with tf.gfile.FastGFile("imageupload/retrained_graph.pb", 'rb') as f:
the change is relative path.
My guess is that the error is where you have this line:
image_path = picture
You've saved the image, so what you really want in the image_path variable is the path to where it's stored on disk. It might be that you're hoping the __str__ function you define in model.py will do this for you, but there's no conversion to string happening in this case.
image_path is an image, not the path:
...
image_path = picture
# Read in the image_data
image_data = tf.gfile.FastGFile(image_path, 'rb').read()
...
get the image's path to the file and pass it to FastGFile
Having some trouble finding how to pass a var captured in a url to my view.
say I have a model like this...
title = models.CharField()
and a title of...
title = 'this is a post'
then how would django capture something in the URL like this...
url/this_is_a_post/
and lookup the model field like this...
x = Post.objects.get(title='this is a post')
I have another URL that is capturing a name with a space in it, and when I use a URL with "_"'s in it, it looks it up correctly, but in this case, it is telling me there is no matching query. I have tried to look in the docs, but I couldn't find anything although I know it has to be there, somewhere.
Use two fileds in your models, say;
class Post(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
and while saving yor Post, you shoud save slug also;
In views;
from django.template.defaultfilters import slugify
post = Post.objects.create(title=title, slug=slugify(title))
this slug will be unique for each post.
In urls.py
url(r'^(?P<slug>[\w-]+)/$', 'myapp.views.post_detail', name='post_detail'),
In views.py
def post_detail(request, slug):
x = Post.objects.get(slug=slug)
in models.py:
title = models.SlugField(unique=True)
in urls.py:
urlpatterns = [
...
url(r'^(?P<title>\d+)/$', views.article_view, name = 'article_detail'),
...
]
in views.py:
def article_view(request, title):
...
article = get_object_or_404(Article, title=title)
...
in template.html:
<a href="{% url 'article_detail' title=article.title %}">
I am using Django 1.5
I have this block of code in a html file
{% for p in latest_posts %}
<li>{{p.title}}</li>
{% endfor %}
If i change p.id to p.title
{% for p in latest_posts %}
<li>{{p.title}}</li>
{% endfor %}
then I get the following error
Reverse for 'detail' with arguments '(u'Second post',)' and keyword arguments '{}' not found.
I want the url to be /title and not /id.
This is my urls.py file
urlpatterns = patterns ('',
url(r'^(?P<title>\w+)/$',
PostDetailView.as_view(),
name = 'detail'
),
)
Should I just use get_absolute_url?
Update
I added the slug field but it still doesn't work
{% url 'blog:detail' p.slug %}
The error I get is
Reverse for 'detail' with arguments '(u'third-post',)' and keyword arguments '{}' not found.
Post model
class Post(models.Model):
title = models.CharField(max_length = 225)
body = models.TextField()
slug = models.SlugField()
pub_date = models.DateTimeField()
modified = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.title
The admin is updated
class PostAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug" : ("title",)}
admin.site.register(Post, PostAdmin)
If this works
{{p.title}}
why doesn't this work
<li>{{p.title}}</li>
update
PostDetailView
class PostDetailView(DetailView):
template_name = 'blogapp/post/detail.html'
def get_object(self):
return get_object_or_404(Post, slug__iexact = self.kwargs['slug'])
One of the things you are going to want to look into is a slugfield which will allow you to have data that is capable of being used in a url. Slugs can contain only letters, numbers, underscores or hyphens. From there you will most likely want to override your model's save method to set and ensure the slugfield is unique. You can then use that field as an identifier for your url. You can then do something like {% url 'blog:detail' slug=p.slug %} assuming that you name the field slug. Also, as pointed out in another answer, if you do use this, you need to fix your url to look for a slug instead.
urlpatterns = patterns ('',
url(r'^(?P<slug>[\w-]+)/$',
PostDetailView.as_view(),
name = 'detail'
),
)
If you're using the generic detail view, it expects either an id or a slug value.
However, in your URL conf, you're specifying the named variable as 'title'. Try changing it to 'slug':
urlpatterns = patterns ('',
url(r'^(?P<slug>\w+)/$',
PostDetailView.as_view(),
name = 'detail'
),
)