hey im new to django so don't be harsh !.im trying to make a blog in django . i need to map the posts in home page to the post page. for that .i have defined a function called get_absulute_url(self) in models.py but it is not recognized in index.html.
when i click on Links nothing happens...i'm not where did i made the mistake !
model.py
from django.db import models
from django.urls import reverse
import posts
# Create your models here.
class post(models.Model):
title=models.CharField(max_length=500)
content=models.TextField()
timestamp=models.DateTimeField(auto_now=False,auto_now_add=True)
updated= models.DateTimeField(auto_now=False,auto_now_add=True)
def get_absulute_url(self):
return reverse("posts:detail", kwargs={'id': self.id})
# return reverse(viewname=posts.views.posts_list,urlconf=any, kwargs={"id": self.id})
views.py
def posts_list(request):#list items
queryset=post.objects.all()
context={
"objectsList":queryset,
"title":"list"
}
return render(request,"index.html",context)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
{% for obj in objectsList %}
Link<br>
{{ obj.title }} <br>
{{ obj.content }} <br>
{{ obj.timestamp }} <br>
{{ obj.updated }} <br>
{{ obj.id }} <br>
{{ obj.pk }} <br>
{% endfor %}
</body>
</html>
url.py
from django.contrib import admin
from django.urls import path
from posts import views as posts_views
urlpatterns = [
path('create/',posts_views.posts_create),
path('<int:id>/', posts_views.posts_detail,name="detail"),
path('',posts_views.posts_list),
path('update/', posts_views.posts_update),
path('delete/', posts_views.posts_delete),
]
Change posts:detail to detail
return reverse("detail", kwargs={'id': self.id})
href="{% url "detail" id=obj.id %}"
Mapping may be the problem but it will throw error before execution.
Still add app_name = 'posts' in urls.py file of your app and try this may work or just use DetailView builtin class still getting error you better add post_detail view to the question above so we can get indepth picture of what you are looking for.
Related
I want to update User database using forms.When I trying to update it remains same the database and not update. So to perform this task ?
forms.py
from django import forms
from django.contrib.auth.models import User
class updateform(forms.ModelForm):
class Meta:
model=User
fields="__all__"
views.py
from django.contrib.auth.models import User
from .forms import updateform
#permission_required('is_superuser')#only superuser can update the data base
def upform(request,id):
emp=User.objects.get(id=id)
if request.method=='POST':
frm=updateform(request.POST,instance=emp)
if frm.is_valid():
frm.save()
return redirect('/')
else:
frm=updateform(instance=emp)
return render(request,'examp.html',{'frm':frm})
examp.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static '/examp.css' %}">
<style>
td,th{
border:1px solid;
text-align:center;
padding:10px;
}
</style>
</head>
<body>
{% include 'include/header.html' %}
<form action="/" method="POST">
{% csrf_token %}
{{ frm.as_p }}
<input type="submit" value="Submit">
</form>
</body>
</html>
How to update the database using this given form.
Why don't you use CBV generic views?
in yourapp/models.py:
from django.db import models
from django.urls import reverse
from django.contrib.auth import get_user_model
# const for get_absolute_url
#that's suffix will be using in your template names look at urls.py,
#if you need u should change it for smth here and in urls!
DETAIL_SUFFIX = '_detail'
class YourModel(models.Model):
name = models.CharField(default='new', max_length=6)
updated_by = models.ForeignKey(get_user_model(), on_delete=models.PROTECT,
related_name='get_upd_by_user')
def __str__(self):
return f'{self.name}'
def get_absolute_url(self):
return reverse(f'{self.__class__.__name__}{DETAIL_SUFFIX}', kwargs={"pk": self.pk})
You need to define the get_absolute_url method. Then reverse will works properly after you update.
in yourapp/views.py:
#views
from django.views.generic.edit import UpdateView
from django.views.generic import DetailView
# AAA
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.mixins import PermissionRequiredMixin
class ProjectSubnetDetailView(LoginRequiredMixin, DetailView):
model = YourModel
template_name = 'your_name_detail.html'
class YourNameUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
model = YourModel
template_name = 'your_name_edit.html'
fields = ('somefield', )
permission_required = ('yourapp.view_yourmodel','yourapp.change_yourmodel')
def form_valid(self, form): # Bind name of current user
form.instance.updated_by = self.request.user
return super().form_valid(form)
Instead of decorator #permission_required in CBV you can use PermissionRequiredMixin(I highly recommend reading about it in the official documentation). In short you must define only in this order:
(LoginRequiredMixin, PermissionRequiredMixin, UpdateView)
First - user must be Authenticated
Second - user must have a rights (or roles, that have a need rights)
Third - thats your generic view for do smth (in this example is update)
For second Attention You must specify in the view those rights that are checked before performing the update in strictly lowercase.
You can define rights in admin panel for some user or create a role and define some rights and add your user into that role. For example i create user and define him some rights for view and change table:
So if your model is called 'YourModel', you should specify 'action_yourmodel'
permission_required = ('yourapp.view_yourmodel','yourapp.change_yourmodel')
in yourapp/urls.py.
from django.urls import path
from .views import YourNameUpdateViewUpdateView, YourNameDetailView
urlpatterns = [
path('YourName/<int:pk>/edit/', YourNameUpdateView.as_view(), name='some_name_edit'),
path('YourName/<int:pk>/detail/', YourNameDetailView.as_view(), name='some_name_detail'),
]
in yourapp/templates/ you have to define 2 templates:
#your_name_detail.html
{% extends '_basetemplate.html' %}
{% block content %}
<div>
<p>{{ object.name }}</p>
</div>
<p>
Update |
</p>
{% endblock content %}
# your_name_edit.html
{% extends '_basetemplate.html' %}
{% block content %}
<h5>Updating {{ object.name }}</h5>
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-sm btn-info ml-2" type="submit">Update</button>
</form>
{% endblock content %}
Still needs working answer.
I have added three apps to my django website: application, blog, and feedback. All three have the same problem: when I click a link, or enter a URL, to any of them, I get a 404 error.
I'm attaching code and other documentation below for one of the problem addons. For further context, if necessary, my full code can be found at https://github.com/kkerwin1/pensdnd.
Directory structure
(venv) kris#adjutant:~/venv/pensdnd$ tree -if
.
./application
./application/admin.py
./application/apps.py
./application/forms.py
./application/__init__.py
./application/migrations
./application/models.py
./application/templates
./application/templates/application.html
./application/templates/application_thanks.html
./application/tests.py
./application/urls.py
./application/views.py
./blog
./blog/admin.py
./blog/apps.py
./blog/models.py
./blog/templates
./blog/templates/blog_list.html
./blog/templates/blog_post.html
./blog/tests.py
./blog/urls.py
./blog/views.py
./feedback
./feedback/admin.py
./feedback/apps.py
./feedback/forms.py
./feedback/models.py
./feedback/templates
./feedback/templates/feedback.html
./feedback/templates/feedback_thanks.html
./feedback/tests.py
./feedback/urls.py
./feedback/views.py
./manage.py
./pensdnd
./pensdnd/settings.py
./pensdnd/static
./pensdnd/static/css
./pensdnd/static/css/main.css
./pensdnd/static/html
./pensdnd/static/html/arvon_rules.html
./pensdnd/static/html/be_a_dm.html
./pensdnd/static/html/community_rules.html
./pensdnd/static/html/guild_rules.html
./pensdnd/static/html/index.html
./pensdnd/static/html/volunteer.html
./pensdnd/static/img
./pensdnd/static/img/carbon_fibre.png
./pensdnd/static/img/github_icon.png
./pensdnd/static/js
./pensdnd/static/misc
./pensdnd/static/templates
./pensdnd/static/templates/base.html
./pensdnd/static/templates/partials
./pensdnd/static/templates/partials/blogbar.html
./pensdnd/static/templates/partials/feedback.html
./pensdnd/static/templates/partials/footer.html
./pensdnd/static/templates/partials/navbar.html
./pensdnd/static/templates/partials/newsbar.html
./pensdnd/static/vid
./pensdnd/urls.py
./pensdnd/views.py
./pensdnd/wsgi.py
./requirements.txt
./pensdnd/urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', views.HomePageView.as_view()),
path('admin/', admin.site.urls),
path('be_a_dm/', views.BeADM.as_view()),
path('blog/', include('blog.urls')),
path('feedback/', include('feedback.urls')),
path('application/', include('application.urls')),
path('guild_rules/', views.GuildRules.as_view()),
path('community_rules/', views.CommunityRules.as_view()),
path('arvon_rules/', views.ArvonRules.as_view()),
path('volunteer/', views.Volunteer.as_view()),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
./blog/urls.py
from . import views
from django.urls import path
urlpatterns = [
path('blog/', views.PostList.as_view()),
path('blog/<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
]
./blog/views.py
from django.shortcuts import render
from .models import Post
from django.views import generic
# Create your views here.
class PostList(generic.ListView):
queryset = Post.objects.filter(status=1).order_by('-created_on')
template_name = 'templates/blog_list.html'
class PostDetail(generic.DetailView):
model = Post
template_name = 'templates/blog_post.html'
./blog/models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
STATUS = (
(0,"Draft"),
(1,"Publish")
)
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
./blogs/templates/blog_list.html
{% extends 'static/templates/base.html' %}
<!doctype html>
<html lang="en">
<head>
<title>
{% block title %}
PensiveDND :: Blog Posts
{% endblock %}
</title>
</head>
<body>
{% block pagecontent %}
<section>
{% for post in post_list %}
<article>
<h3>{{ post.title }}</h3>
<p>{{ post.author }} | {{ post.created_on }}</p>
<p>{{ post.content|slice:":200" }}
Read More
</article>
</section>
{% endblock %}
</body>
</html>
./blogs/templates/blog_post.html
{% extends 'static/templates/base.html' %}
<!doctype html>
<html lang="en">
<head>
<title>
{% block title %}
PensiveDND :: Blog :: {{ post.title }}
{% endblock %}
</title>
</head>
<body>
{% block pagecontent %}
<section>
<h2>{{ post.title }}</h2>
<p>{{ post.author }} | {{ post.created_on }}</p>
<p>{{ post.content | safe }}</p>
</section>
{% endblock %}
</body>
</html>
In "pensdnd/urls.py", you are missing the trailing slashes after your app name
for example
path('feedback', include('feedback.urls')),
should be
path('feedback/', include('feedback.urls')),
Unable to access html files. There are no errors in your urls.py file. At least for the blog app. When I run the code, I don't get a 404 error with different edits. According to the Github codes, I changed the DIRS section in the templates field under settings.py to 'templates' and moved the html files you used in your blog application here. There was no problem. Editing all your code can be difficult, but that's where the problem lies.(Note that I only control the blog app.)
also, you will get an error because you don't use {% endfor %}.
{% for post in post_list %}
<article>
<h3>{{ post.title }}</h3>
<p>{{ post.author }} | {{ post.created_on }}</p>
<p>{{ post.content|slice:":200" }}
Read More
</article>
If you have set templates location, you should just use template_name = 'blog_list.html instead of template_name = 'templates/blog_list.html'.
Please check these things again. As I said, the problem is caused by the use of static and templates. not urls.
i keep getting an error (404) page when i run my server for a django when i click the link to a post detail. I think nothing is wrong with my code so i need help to locate why i'm getting the error.
this is my views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .models import Post
from django.utils import timezone
# Create your views here.
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('created_date')
return render(request, 'blog2app/home_post_list.html', {'posts': posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog2app/postdetail.html', {{'post': post}})
this is my blog2app\urls.py
from django.urls import path
from . import views
urlpatterns = [
path(r'^$', views.post_list, name="homepage"),
path(r'^post/(?P<pk>\d+)/$', views.post_detail, name='post_detail'),
]
this is my blog2/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(r'^admin/$', admin.site.urls),
path(r'^$', include('blog2app.urls')),
]
this is my home_post_list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for post in posts %}
<p><h4>Published: {{ post.published_date }}</h4></p>
<h1><strong> {{ post.title }} </strong></h1><br>
{% endfor %}
</body>
</html>
this is my detailpost.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if post.published_date %}
{{ post.published_date }}
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.body|linebreaksbr }}
</body>
</html>
this is the error page on chrome.
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/
Using the URLconf defined in blog2.urls, Django tried these URL patterns, in this order:
^admin/$
^$
The empty path didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page
the development server is showing no error.
blog2app is my app name.
blog2 is my projectname.
i am using pycharm idle for development.
i will be very happy if anyone can suggest any tutorial video particularly for creating blogs with django.
i changed my detailpost.html to
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ posts.published_date }}
<h1>{{ posts.title }}</h1>
<p>{{ posts.body|linebreaksbr }}
</body>
</html>
i changed my views.py to
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .models import Post
from django.utils import timezone
# Create your views here.
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('created_date')
return render(request, 'blog2app/home_post_list.html', {'posts': posts})
def post_detail(request, pk=None ):
post = Post.objects.get(pk=pk)
context = {'posts': post}
return render(request, 'blog2app/postdetail.html', context)
i changed my home_post_list.html to
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for post in posts %}
<p><h4>Published: {{ post.published_date }}</h4></p>
<h1><strong> {{ post.title }} </strong></h1><br>
{% endfor %}
</body>
</html>
and i stopped seeing the error.
My conclusion is i was using the post in
post = Post.objects.get(pk=pk)
to call my primary key instead of using posts in
context = {'posts': post}
Max Goodridge django tutorial really helped me.
I have created a class in the models.py containing the information of articles I want to insert in a website
from django.db import models
from django.urls import reverse
class Article(models.Model):
"""
Model representing an article.
"""
title = models.CharField(max_length=200)
authors = models.CharField(max_length=200)
summary = models.TextField(max_length=1000, help_text='Enter a brief description of the article')
content = models.TextField(max_length=100000)
def __str__(self):
"""
String for representing the Model object.
"""
return self.title
def get_absolute_url(self):
"""
Returns the url to access a detail record for this article.
"""
return reverse('article-detail', args=[str(self.id)])
After that, I have inserted an article using the admin panel of Django and saved it.
Then, I have created the index.html shown below calling the articles in the database
<!DOCTYPE html>
<html lang="en">
<head>
{% block title %}{% endblock %}
</head>
<body>
{% block sidebar %}<!-- insert default navigation text for every page -->{% endblock %}
{% block content %}<!-- default content text (typically empty) -->
<!-- Articles -->
<div class="articles">
<h1>Titolo: {{ article.title }}</h1>
<p><strong>Autori:</strong> {{ article.authors }}</p>
<p><strong>Riepilogo:</strong> {{ article.summary }}</p>
<p><strong>Testo:</strong> {{ article.content }}</p>
</div>
{% endblock %}
</body>
</html>
But the article is not shown despite being in the database (see prints below)
EDIT1: inserted views.py as requested
from django.shortcuts import render
from .models import Article
# Create your views here.
def index(request):
"""
View function for home page of site.
"""
# Render the HTML template index.html with the data in the context variable
return render(
request,
'index.html',
)
You are not including any articls in your template context:
return render(
request,
'index.html',
)
You could include the articles in the template context with:
articles = Article.objects.all()
return render(
request,
'index.html',
{'articles': articles}
)
Then in the template you need to loop through the articles.
<!-- Articles -->
<div class="articles">
{% for article in articles %}
<h1>Titolo: {{ article.title }}</h1>
<p><strong>Autori:</strong> {{ article.authors }}</p>
<p><strong>Riepilogo:</strong> {{ article.summary }}</p>
<p><strong>Testo:</strong> {{ article.content }}</p>
{% endfor %}
</div>
views.py
from django.shortcuts import render_to_response
from models import Post
def getRecentPosts(request):
posts = Post.objects.all()
# sort by chronological order
sorted_posts = posts.order_by('-pub_date')
# display all posts
return render_to_response('posts.html', {'posts': sorted_posts})
posts.html
<html>
<head>
<title>My Django Blog</title>
</head>
<body>
{% for post in posts %}
<h1>{{post.title}}</h1>
<h3>{{post.pub_date}}</h3>
{{ post.text }}
{% endfor %}
</body>
This code works fine & prints the proper data.... However if i change
return render_to_response('posts.html', {'posts': sorted_posts})
to
return render_to_response('posts.html', {'po': sorted_posts})
and
{% for post in posts %} to {% for post in po %}
in posts.html
It fails to generate any data..... So what is the relation between the dictionary name in view and template