models.py
from django.db import models
class Blog(models.Model):
time = models.DateTimeField(auto_now_add = True)
title = models.CharField(max_length = 100)
slug = models.SlugField()
perex = models.TextField()
content = models.TextField()
#models.permalink
def get_absolute_url(self):
return ('blog', [self.slug])
def __unicode__(self):
return self.title
class Meta:
ordering = ['-time']
views.py
from django.shortcuts import render_to_response, get_object_or_404
from blog.models import Blog
def blog_entries(request):
blogs = Blog.objects.all()[0:3]
title = "Blogs"
return render_to_response('blog/blog.djhtml', {'blogs': blogs, 'title': title,})
def blog_single_entry(request, slug):
blog = get_object_or_404(Blog, slug=slug)
title = blog.title
return render_to_response('blog/single.djhtml', {'blog': blog, 'title': title,})
url.py
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'kablog.views.home', name='home'),
# url(r'^kablog/', include('kablog.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
url(r'^blog/', 'blog.views.blog_entries', name='blog'),
url(r'^blog/(?P<slug>[-\w]+)/', 'blog.views.blog_single_entry', name='single_blog'),
)
template
{% extends 'base.djhtml' %}
{% block title %}| {{title}}{% endblock %}
{% block content %}
<div class="hero-unit">
<h1>Welcome to my Blog</h1>
<p>Where knowledge is always free</p>
<p>
<a class="btn btn-primary btn-large">
Read More
</a>
</p>
</div>
<div class="row">
{% for blog in blogs %}
<div class="span4">
<h2>{{blog}}<small>{{blog.time|date:"M D d Y"}}</small></h2>
<p>{{blog.perex|safe}}</p>
<a class="btn" href="{{ blog.get_absolute_url }}">
Read More
</a>
</div>
{% endfor %}
</div>
{% endblock %}
blog.get_absolute_url does not return a slug and also even though i have have try to browse "blog/my-first-blog" the browser just displays the home blog not the single_blog and it doesn't return a 404 error if you browse "blog/dgdsghdsfhdsfhds"
I also tried that but I can't make it work, so I try other approach
class Blog(models.Model):
[......]
#property
def get_blog_url(self):
return reverse('blog', args=[self.slug])
<a class="btn" href="{{ blog.get_blog_url }}">
Read More
</a>
You need to make #models.permalink instead #permalink.
Related
I'm currently using UpdateView to add edit functionality to my Django project. It's working correctly insofar as I can edit my data, however when I submit the new data, it returns a NoReverseMatch error:
NoReverseMatch at /MyHealth/edit/8
Reverse for 'health_hub_history' not found. 'health_hub_history' is not a valid view function or pattern name.
I've researched it and added a get_absolute_url to my model, but it isn't working. Any help would be appreciated!
models.py:
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
class HealthStats(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(auto_now=True)
weight = models.DecimalField(max_digits=5, decimal_places=2)
run_distance = models.IntegerField(default=5)
run_time = models.TimeField()
class Meta:
db_table = 'health_stats'
ordering = ['-date']
def get_absolute_url(self):
return reverse('health_hub_history')
def __str__(self):
return f"{self.user} | {self.date}"
urls.py:
from django.urls import path
from django.contrib.staticfiles.storage import staticfiles_storage
from django.views.generic.base import RedirectView
from . import views
app_name = 'HealthHub'
urlpatterns = [
path('', views.home, name='home'),
path('MyHealth/', views.health_hub, name='health_hub'),
path('MyHealth/update', views.UpdateHealth.as_view(), name='health_hub_update'),
path('MyHealth/history', views.health_history, name='health_hub_history'),
path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url("favicon.ico"))),
path('MyHealth/delete/<item_id>', views.delete_entry, name='health_hub_delete'),
path('MyHealth/edit/<int:pk>', views.EditHealth.as_view(), name='health_hub_edit'),
]
Views.py:
class EditHealth(UpdateView):
model = HealthStats
template_name = 'health_hub_edit.html'
fields = ['weight', 'run_distance', 'run_time']
health_hub_edit.html:
{% extends 'base.html' %}
{% load static %}
{%load crispy_forms_tags %}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 text-center">
<h1>Edit my Data</h1>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-auto text-center p-3">
<form method="post" style="margin-top: 1.3em;">
{{ form | crispy }}
{% csrf_token %}
<button type="submit" class="btn btn-signup btn-lg">Submit</button>
</form>
</div>
</div>
<div class="row justify-content-center">
</div>
</div>
{% endblock content %}
This error occurs because the django couldn't resolve the url
you didn't specify a primary key to base the query on.
you should modify this function
def get_absolute_url(self):
return reverse('health_hub_history', kwargs={'user': self.user})
also that health_history url is it a class based view you should add .as_view() to the end and observe camel casing
Lastly your url should observe the primary key specified
You can do this:
class EditHealth(UpdateView):
model = HealthStats
template_name = 'health_hub_edit.html'
fields = ['weight', 'run_distance', 'run_time']
def get(self, request):
return HttpResponse("health_hub")
def post(self, request):
# do something
return redirect("health_hub")
urlpatterns = patterns('',
url('', views.home, name='home'),
url('MyHealth/', views.health_hub, name='health_hub'),
url('^MyHealth/update', views.UpdateHealth.as_view(), name='health_hub_update'),
url('MyHealth/history', views.health_history, name='health_hub_history'),
url('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url("favicon.ico"))),
url('MyHealth/delete/<item_id>', views.delete_entry, name='health_hub_delete'),
url('MyHealth/edit/<int:pk>', views.EditHealth.as_view(), name='health_hub_edit'),
)
This will solve your problem
I found the answer to this issue here:
https://stackoverflow.com/a/48068932/19053957
Looks like all I need to do was refer to the app name prior to the name of the URL in get_absolute_url()!
I want to show the topic title in the website template url link on django 3.
currently opening the topic id number.
for example : http://localhost:8000/detay/4
for example : http://localhost:8000/detay/2
for example : http://localhost:8000/detay/1
but I want to do it this way
for example : http://localhost:8000/detay/1/this-is-topic-title
or
for example : http://localhost:8000/detay/3/this-is-topic-title
.
.
.
views.py
from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import *
# Create your views here.
def index(request):
girdiler = Deneme1Model.objects.filter(yuklemeTarihi__lte=timezone.now()).order_by('-yuklemeTarihi')
context ={
'girdiler':girdiler
}
return render(request, 'deneme1Uygulama/index.html', context)
def ekle(request):
return render(request, 'deneme1Uygulama/ekle.html')
def detay(request, pk):
girdiler = Deneme1Model.objects.filter(pk=pk)
context ={
'girdiler':girdiler
}
return render(request, 'deneme1Uygulama/detay.html', context)
def sayfaYok(request):
return render(request, 'deneme1Uygulama/404.html')
urls.py
from django.urls import path
from .import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', views.index, name='index'),
path('ekle/', views.ekle, name='ekle'),
path('detay/<int:pk>', views.detay, name='detay'),
path('404/', views.sayfaYok, name='sayfaYok'),
]
urlpatterns +=static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
models.py
from django.db import models
from django.utils import timezone
# Create your models here.
class Deneme1Model (models.Model):
baslik = models.CharField(max_length=50, verbose_name='BAŞLIK')
aKaydi = models.CharField(max_length=50, verbose_name='A KAYDI')
dosyaYukle = models.FileField(upload_to='media', verbose_name='DOSYA YÜKLE')
yuklemeTarihi =models.DateTimeField(default =timezone.now)
yayinKontrol = models.BooleanField(default=True)
def __str__(self):
return self.baslik
detay.html
{% block content %}
<div class="row">
{% if girdiler %}
{% for girdi in girdiler %}
<div class="col-12 d-flex justify-content-center">
<div class="card w-100">
<img class="card-img-top img-fluid umaxhe20" src=" {{ girdi.dosyaYukle.url }} " alt="Card image cap">
<div class="card-body">
<h5 class="card-title"> {{ girdi.baslik }} </h5>
<p class="card-text"> {{ girdi.aKaydi }} </p>
{{ girdi.yuklemeTarihi }}
</div>
</div>
</div>
{% endfor %}
{% else %}
{% url 'sayfaYok' %}
{% endif %}
</div>
{% endblock content %}
Not tested but probably something like this
urls.py
urlpatterns = [
path('detay/<int:pk>', views.detay, name='detay'),
path('detay/<int:pk>/<string:topic>', views.detay_topic, name='detay-topic'),
]
views.py
def detay_topic(request, pk, topic):
...
I'm learning django, and I have a problem, I'm doing a virtual store and when I click on add a product to the shopping cart you should redirect me to another page, but can not find it, this is my code and my error:
django.template.exceptions.TemplateDoesNotExist: productos/carritocompras_form.html
detalle.html
<div class="fixed-action-btn" style="bottom:90px;">
<form action="{% url 'aniadir_carrito' %}" method="post">
{% csrf_token %}
<input type="hidden" name="usuario" value="{{request.user.pk}}">
<input type="hidden" name="produto" value="{{object.pk}}">
<input type="hidden" name="precio" value="{{object.precio}}">
<button class="btn-floating btn-large red pulse">
<i class="large material-icons">add_shopping_cart</i>
</button>
</form>
</div>
<div class="fixed-action-btn">
<a class="btn-floating btn-large red pulse">
<i class="large material-icons">add_shopping_cart</i>
</a>
<ul>
</ul>
</div>
url.py
from django.conf import settings
from django.urls import include, path
from django.conf.urls.static import static
from django.contrib import admin
from django.views.generic import TemplateView
from django.views import defaults as default_views
from tienda.users.views import (
Indice, ListarProductos, DetalleProducto, ComentarioProducto, Ingresar, Salir, CambiarPerfil,
CarritoCompras, AniadirCarrito, ListarCarrito, ListarCarritoPendientes, ListarCarritoFinalizadas, EliminarCarrito
)
urlpatterns = [
path('', Indice.as_view(), name="indice"),
path("listado_productos", ListarProductos.as_view(), name="listado_productos"),
path("detalle_producto/<int:pk>/", DetalleProducto.as_view(), name="detalle_producto"),
path("crear_comentario/", ComentarioProducto.as_view(), name="crear_comentario"),
path("ingresar/", Ingresar.as_view(), name="ingresar"),
path("salir/", Salir.as_view(), name="salir"),
path("editar_perfil/", CambiarPerfil.as_view(), name="editar_perfil"),
path("aniadir_carrito", AniadirCarrito.as_view(), name="aniadir_carrito"),
path("listar_carrito", ListarCarrito.as_view(), name="listar_carrito"),
path("listar_pendientes", ListarCarritoPendientes.as_view(), name="listar_pendientes"),
path("listar_finalizado", ListarCarritoFinalizadas.as_view(), name="listar_finalizado"),
path("eliminar_carrito", EliminarCarrito.as_view(), name="eliminar_carrito"),
# Django Admin, use {% url 'admin:index' %}
path(settings.ADMIN_URL, admin.site.urls),
# Your stuff: custom urls includes go here
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
views.py
class AniadirCarrito(LoginRequiredMixin, CreateView):
model = CarritoCompras
fields = ('usuario','producto', 'precio',)
success_url = reverse_lazy('indice')
login_url = 'ingresar'
models.py
class CarritoCompras(models.Model):
producto = models.ForeignKey(Producto, related_name="producto_carrito", on_delete=models.CASCADE)
usuario = models.ForeignKey(get_user_model(), related_name="carrito_usuario", on_delete=models.CASCADE)
precio = models.IntegerField()
direccion = models.CharField(max_length=300)
datos_payu = models.CharField(max_length=600)
comprado = models.BooleanField(default=False)
pendiente = models.BooleanField(default=False)
def __str__(self):
return "{} {}".format(self.usuario)
I am trying to populate a navbar "dropdown-menu" with individual "dropdown-item"'s populated from data in the sqlite3 DB.
I have something similar working on other pages but I cant get it to work in my navbar.
I am creating a record label, and want the list of artists populated from entries in the DB. I have found one tutorial on doing something similar in php, but doesn't translate, and there doesn't seem to be anything either on youtube or here other than populating form data.
Any help is greatly appreciated, as I have been trying to get it working for about a week now. I know it should be simple, but im missing something.
the app is called "music"
models.py
class Artist(models.Model):
artist_name = models.CharField(max_length=250, default='')
artist_logo = models.FileField()
artist_url = models.URLField(blank=True)
def __str__(self):
return self.artist_name
class Release(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
release_title = models.CharField(max_length=500)
release_cover = models.FileField()
release_duration = models.IntegerField()
def __str__(self):
return self.release_title
class Track(models.Model):
release = models.ForeignKey(Release, default='', on_delete=models.CASCADE)
artist = models.ForeignKey(Artist, default='', on_delete=models.CASCADE)
track_title = models.CharField(max_length=200)
track_version = models.CharField(max_length=200)
track_genre = models.CharField(max_length=100)
track_duration = models.IntegerField()
track_number = models.SmallIntegerField()
class Meta:
ordering = ["track_number"]
def __str__(self):
return self.track_title
views.py
from django.contrib.auth import authenticate, login
from django.views import generic
from django.views.generic import ListView, View
from .models import Artist, Track, Release
from .forms import UserForm
# class IndexView(ListView):
# template_name = 'music/index.html'
class ReleaseView(generic.ListView):
template_name = 'music/releaselist.html'
context_object_name = 'all_releases'
def get_queryset(self):
return Release.objects.all()
class ArtistView(generic.ListView):
model = Artist
template_name = 'music/artistlist.html'
context_object_name = 'all_artists'
def get_queryset(self):
return Artist.objects.all()
class DetailView(generic.DetailView):
model = Release
template_name = 'music/detail.html'
urls.py (Main)
from django.contrib import admin
from django.urls import path, include, re_path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
# include urls from the music app
path('music/', include('music.urls'))
urls.py ("music" aka the app urls)
from django.contrib import admin
from django.urls import path, include, re_path
from . import views
# defined the app name in case the same fields are used in other apps
app_name = 'music'
urlpatterns = [
# no info past music return index EG /music/
# path('', views.IndexView.as_view(), name='index'),
# albums/releases
re_path(r'^release/$', views.ReleaseView.as_view(), name='release'),
# looking for music page with album id afterwards /music/1
re_path(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name="detail"),
re_path(r'^(?P<pk>[0-9]+)/$', views.ArtistView.as_view(), name="artist"),
base.html
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Artists
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
{% for artist in all_artists %}
<li><a class="dropdown-item" href="#">{{ artist.artist_id }}</a></li>
{% endfor %}
</div>
</li>
Update:
Here is my releases.html which works using similar code, and at the bottom has a test which looks like the for loop is incorrect
{% extends 'music/base.html' %}
{% block title %}KOLD FUZEON: Releases{% endblock %}
{% block body %}
{% if all_releases %}
<ul>
{% for release in all_releases %}
<div class="releaseitem">
<li>{{ release.artist }} - {{ release.release_title }}</li>
<li><a href="{% url 'music:detail' release.id %}"</a><img src="{{ release.release_cover.url }}" style="width: 300px"></li>
</div>
{% endfor %}
</ul>
{% else %}
<h3>We currently dont have any releases yet.</h3>
{% endif %}
{#basic test for the artist list to be printed to screen#}
<ul>
<li>test1</li>
{% for artist in all_artists %}
<li>test2</li>
{% endfor %}
</ul>
{% endblock %}
In your View.py you have ArtistView where template is artistlist.html and your context is all_artist & you get all objects from db.
Code:
class ArtistView(generic.ListView):
model = Artist
template_name = 'music/artistlist.html'
context_object_name = 'all_artists'
def get_queryset(self):
return Artist.objects.all()
Now i believe you have a template named artistlist.html. If not create it in templates in which you will use for Loop
to render artist list so the code should be this for artistlist.html:
{% extends 'music/base.html' %}
{% block body %}
<h1>Artists!</h1>
<ul>
{% for artist in all_artists %}
<li class="artist">
<h1>
<a href='/music/{{ artist.id }}'>{{artist.artist_name }}</a>
</h1>
</li>
{% endfor %}
</ul>
</div>
{% endblock %}
You can Render Artist list in Base.html.
Using: Context Processor
First Create a file named context_processors.py in your App.Then add this code in that file.
from .models import Artist
def basetest(request):
hello = Artist.objects.values_list("artist_name", flat=True)
return {
'testname': hello
}
After that, open Settings.py and find context_processors and add the following settings 'yourapp.context_processors.add_variable_to_context'.
Settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
#This one is from my code so set it according to you
#appname.context_processors.function_name_context_processor.py',
'blog.context_processors.basetest',
],
},
},
]
After this just place {{ testname }} in your base.html according to your need. it will work. No need for looping just the interpolation will render you a list. Format it according to your need by following this doc
I believe there is some problem in the name of the 'key' that you are passing in the context.
In ReleaseView the context object name is all_releases, while you are trying to iterate on "all_artists".
Even if these changes not work, you can always try running your code on a normal view instead of the a generic view and pass the context in the template.
I have a django blog that I'm working on and I've got the first part of the blog working in which the blog displays the various entry's from the database. However when I go to click on a particular blog post it doesn't redirect me to the detailed view, it just kinda redirects me back to the blog where I can see all the blog posts:
By clicking on this in the blog.html I want it to link to the particular post in the post.html
<h2>{{ object.title }}</h2>
urls.py
from django.conf.urls import patterns, url
from . import views, feed
urlpatterns = patterns(
'',
url(r'^feed/$', feed.LatestPosts(), name="feed"),
url(r'^', views.BlogIndex.as_view(), name="blog"),
url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
)
models.py
from django.db import models
from django.core.urlresolvers import reverse
class Tag(models.Model):
slug = models.SlugField(max_length=200, unique=True)
def __str__(self):
return self.slug
class EntryQuerySet(models.QuerySet):
def published(self):
return self.filter(publish=True)
class Entry(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=200, null=True)
body = models.TextField()
slug = models.SlugField(max_length=200, unique=True)
publish = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
tags = models.ManyToManyField(Tag)
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES, null=True, blank=True)
objects = EntryQuerySet.as_manager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("entry_detail", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Blog Entry"
verbose_name_plural = "Blog Entries"
ordering = ["-created"]
views.py
from django.views import generic
from . import models
class BlogIndex(generic.ListView):
queryset = models.Entry.objects.published()
template_name = "blog.html"
paginate_by = 3
class BlogDetail(generic.DetailView):
model = models.Entry
template_name = "post.html"
blog.html
{% include 'head.html' %}
{% include 'navbar.html' %}
<div class="container">
{% load django_markdown %}
<br>
<br>
{% for object in object_list %}
<div class="post">
<h2>{{ object.title }}</h2>
<p class="meta"></p>
<p class="meta">
{{ object.created }} |
Tagged under {{ object.tags.all|join:", " }}
</p>
{{ object.body|markdown }}
</div>
{% endfor %}
<hr class="featurette-divider">
{% if is_paginated %}
<ul class="pager">
<li {% if not page_obj.has_previous %}class="disabled"{% endif %}><a {% if page_obj.has_previous %}href="?page={{ page_obj.previous_page_number }}"{% endif %}>Prev</a></li>
<li {% if not page_obj.has_next %}class="disabled"{% endif %}><a {% if page_obj.has_next %}href="?page={{ page_obj.next_page_number }}"{% endif %}>Next</a></li>
</ul>
{% endif %}
</div>
{% include 'footer.html' %}
post.html
{% load django_markdown %}
{% for object in object_list %}
<div class="post">
<h2>{{ object.title }}</h2>
<p class="meta">
{{ object.created }} |
Tagged under {{ object.tags.all|join:", " }} <p> Created by
{{ object.author }} </p>
</p>
{{ object.body|markdown }}
</div>
I've also got another url.py which points the blog url to all the urls in the blog app. Don't know if that helps:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'website.views.home', name='home'),
url(r'^about/', 'website.views.about', name='about'),
url(r'^contact/', 'contact.views.contact', name='contact'),
url(r'^markdown/', include("django_markdown.urls")),
url(r'^blog/', include('blog.urls')),
]
When you define the urls with this:
url(r'^', views.BlogIndex.as_view(), name="blog"),
url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
The second entry matches /entry, which is not what you expect. I think that in your case, you should define it like this:
url(r'^$', views.BlogIndex.as_view(), name="blog"),
url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
^$ will match /, but not /entry/...
Problem solved thanks to Brandon. Rearranged my url patterns from the most specific to the least specific (longest to shortest). And restarted the server.
urlpatterns = patterns(
'',
url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"),
url(r'^feed/$', feed.LatestPosts(), name="feed"),
url(r'^', views.BlogIndex.as_view(), name="blog"),
)