urlpatterns not behaving as expected - django

I have specified a url to list students and a url to display the student details however the url for the student details doesnt seem to work.
The ursl.py looks like this:
urlpatterns = [
path('', views.SchoolListView.as_view(), name='list'),
path('<int:pk>/',views.SchoolDetailView.as_view(),name='detail'),
path('create/', views.SchoolCreateView.as_view(),name='create'),
path('update/<int:pk>/',views.SchoolUpdateView.as_view(),name='update'),
path('delete/<int:pk>/',views.SchoolDeleteView.as_view(),name='delete'),
path('students', views.StudentListView.as_view(), name='student_list'),
path('students/<int:pk>/',views.StudentDetailView.as_view(),name='student_details'),
]
but when I click on the actual student it doesnt take me to basic_app/students/1 (for example) but to basic_app/1
Also when I manually type /basic_app/students/1 I get an error which says:
NoReverseMatch at /basic_app/students/1/
Reverse for 'update' with keyword arguments '{'pk': ''}' not found. 1
pattern(s) tried: ['basic_app/update/(?P<pk>[0-9]+)/$']
no reverse error
my views:
class StudentListView(ListView):
context_object_name = 'students'
model = models.Student
class StudentDetailView(DetailView):
context_object_name = 'student_details'
model = models.Student
template_name = 'basic_app/student_detail.html'
the model:
class Student(models.Model):
name = models.CharField(max_length=150)
age = models.PositiveIntegerField()
school = models.ForeignKey(School, related_name='students', on_delete=models.CASCADE)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("basic_app:student_details",kwargs={'pk':self.pk})
The student_details.html template:
{% extends 'basic_app/basic_app_base.html' %}
{% block body_block %}
<div class="container jumbotron">
<h2>Student Details:</h2>
<p>Name: {{student_details.name}}</p>
<p>Principal: {{student_details.age}}</p>
<p>Location: {{student_details.school}}</p>
<!-- <div class="container">
<a class="btn btn-primary" href="{% url 'basic_app:update' pk=school_details.pk %}">Update</a>
<a class="btn btn-danger" href="{% url 'basic_app:delete' pk=school_details.pk %}">Delete</a>
Cancel
</div> -->
{% endblock %}
What have I done wrong?`

The commented-out section in your student_details.html may be producing the error. Delete that part and it should work:
{% extends 'basic_app/basic_app_base.html' %}
{% block body_block %}
<div class="container jumbotron">
<h2>Student Details:</h2>
<p>Name: {{student_details.name}}</p>
<p>Principal: {{student_details.age}}</p>
<p>Location: {{student_details.school}}</p>
{% endblock %}

Related

How to delete a record through a button in django

I have created a model Announcement in models.py file
class Announcement(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
def __str__(self):
return self.title
And for deleting a record of Announcement I have created the following view
def AnnouncementDelete(request, pk):
announcement = get_object_or_404(Announcement, pk=pk)
if request.method=='POST':
announcement.delete()
return redirect('/')
return render(request, 'classroom/announcement_confirm_delete.html', {'announcement': announcement})
The delete view of announcement (that is AnnouncementDelete) has the following url
path("delete/<int:pk>/", view=views.AnnouncementDelete, name="AnnouncementDelete"),
If i enter
http://127.0.0.1:8000/classroom/delete/3
on browser it is deleting the Announcement having pk = 3
Now I want a button to directly delete my record without the need of typing http://127.0.0.1:8000/classroom/delete/3 on browser
I have tried the following methods in my allannouncement.html file
{% extends "classroom/base.html" %}
{% block content %}
<h1>Announcements</h1>
{% for announcement in announcements %}
<!-- starting loop (posts is keyword from view) -->
<div style="border-style: solid;">
{% if announcement.teacher.user == request.user %}
<div>
Delete
</div>
{% endif %}
{{ announcement.pk }}
<a class="mr-2">Posted by: {{ announcement.teacher }}</a>
<h2><a class="article-title">{{ announcement.title }}</a></h2>
<p class="article-content">{{ announcement.content}}</p>
</div>
{% endfor %}
{% endblock content %}
but it is giving the following error
NoReverseMatch at /classroom/allannouncement/
Reverse for 'AnnouncementDelete' with no arguments not found. 1 pattern(s) tried: ['classroom/delete/(?P<pk>[0-9]+)/$']
then I also tried passing pk with url like
Delete
But it is giving the following error
TemplateSyntaxError at /classroom/allannouncement/
Could not parse the remainder: ',' from ','
Remove common #refer this
Delete
instead of a link add a form.
Add
{% load crispy_forms_tags %}
in your html file and then add
{% if announcement.teacher.user == request.user %}
<div>
<form action="{% url 'classroom:AnnouncementDelete' announcement.id %}"
method="post">
{% csrf_token %}
<input type="submit" value="Delete">
</form>
</div>
{% endif %}

how do i create a profile page that shows all users post to the user and to other users

am new to Django and am trying to create a blog site where users can sign up and post articles, but my problem is how can I display a user's post on the user's profile page so that when other users reading the post clicks on the author's name it takes them to the post.author's profile page with the post.author's recent post listed and not the request.user's post. here is my code.
here is accounts/views.py
views.py
#login_required()
def user_profile_view(request, username):
post = User.objects.filter(courses__author=username)
context = {'courses': courses}
return render(request, 'accounts/user_profile_view.html', context)
and here is post/models.py
models.py
class Posts(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
cover = ProcessedImageField(upload_to='post_featured_image',
processors=[ResizeToFill(600, 300)],
format='png',
options={'quality': 80},
blank=True)
slug = models.SlugField()
title = models.CharField(max_length=200)
body = models.TextField()
summary = models.TextField(max_length=200)
here is the template
post_list.html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div class="col-lg-6">
{% for course in courses_list %}
<div class="central-meta item">
<div class="user-post">
<div class="friend-info">
{% if post.author.profile.avatar %}
<figure>
<img src="{{ post.author.profile.avatar.url }}" alt="">
</figure>
{% else %}
<img src="{% static 'default.ico' %}" alt="">
{% endif %}
<div class="friend-name">
<ins>{{ course.author.get_full_name|title }}</ins>
<span>published: {{ post.published }}</span>
</div>
<div class="post-meta">
{% if course.cover %}
<img src="{{ post.cover.url }}" alt="">
{% endif %}
<div class="friend-name">
<ins>{{ course.title|title }}</ins>
</div>
<div class="description">
<p><span>{{ post.summary|capfirst }}</span></p>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
here is my accounts/urls.py
urls.py
app_name = 'accounts'
urlpatterns = [
path('accounts/profile/<str:username>/', user_profile_view, name='user_profile'),
]
you should be able do that, easy and via lots of ways.
make a post model like this:
class Post(models.Model):
author = foreign_key(User, related_name="posts", on_delete=models.CASCADE)
title = char_field()
content ........
so with that related name you will be able to reverse from user to its posts too!.
in your template do this:
{{ post.author }}
this link will redirect user to the posts author dashboard if you arrange the urls pattern correctly.
then for sorting authors posts, you have to pass the dashboard_owner to the template and use this name instead of user which normally will refer to the request.user -> user who are visiting the page
{% for post in dash_owner.posts.all %}
<li> <a href="{{ post.get_abslute_url }}" target="_blink">
{{ post.title }} </a> </li>
{% endfor %}
in views.py
def dashboard(request, owner_id=None)
if owner_id:
dash_owner = get_or_404(User, id=owner_id)
elif request.user.is_authenticated:
dash_owner = User.objectd.get(id=request.user.id)
return render(request, 'dashboard.html', {'dash_owner': dash_owner})
in urls.py -> urlpatterns:
path('dashboard/<int:owner_id>/', views.dashboard, name="dashboard")
this is the idea behind that, but for get the better result, you may need to clearly define the get_absolute_url of User model, to give you the url which machts to
'dashboard/<int:id/'
or another way is instead of that, do this:
{{ post.author }}

redirecting with primary key from views.py

I have a view
(user_list.html)
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="list_main">
<div class="container">
{% for user in user_list %}
<ul>
<li><a href="{% url 'myapp:detail' pk=user.pk %}">
<div class="jumbotron">
<h4 class="list_content">{{user.name}}</h4>
</div>
</a></li>
</ul>
{% endfor %}
<div class="bttn">
<p><a type="button" class="btn btn-primary" href="{% url 'myapp:user' %}">Add</a></p>
</div>
</div>
</div>
{% endblock %}
Here with the help of
<p><a type="button" class="btn btn-primary" href="{% url 'myapp:user' %}">Add</a></p>
I am calling (views.py --> UserView)
def UserView(request):
response = requests.get('https://randomuser.me/api')
data = response.json()
title = data['results'][0]['name']['title']
first = data['results'][0]['name']['first']
last = data['results'][0]['name']['last']
final_name = " ".join([first,last])
#############################################
final_name = ". ".join([title, final_name]) #Final name of the user
#############################################
agee = data['results'][0]['dob']['age'] # age of the user
user = UserData.objects.create( name = final_name, age= agee, gender = gender)
user.save()
return redirect('detail', pk=user.pk) #This is not working
what I want to do is whenever the button from template (user_list.html) is clicked.
I want to enter this function in my views.py file perform the operations and redirect to
(path('detail/<int:pk>/', views.UserDetailView.as_view(), name='detail'),)
My views.UserDetailView
class UserDetailView(DetailView):
model = UserData
context_object_name = 'user_detail'
template_name = 'user_detail.html'
As shown in the code in( UserView(request) ), I have tried "return redirect('detail', pk=user.pk) "
this does not work.
Also please tell me if there is more neat and efficient way available to perform operations present in
( UserView(request) ) when button is clicked in ( user_list.html ) and then redirect from "UserView" to ((path('detail//', views.UserDetailView.as_view(), name='detail'),))
You missed app name myapp when using redirect:
return redirect('myapp:detail', pk=user.pk)

Reverse for 'user_review_list' not found. 'user_review_list' is not a valid view function or pattern name

Even after going through similar STACKOVERFLOW solutions this doubt was not solved.
I have also been through other resources.
Been engaged in django since 2 days only !! :)
project -> winerama
app ->reviews
my views.py
def review_list(request):
latest_review_list =Review.objects.order_by('-pub_date')[:9]
context ={'latest_review_list': latest_review_list}
return render(request, 'reviews/review_list.html',context)
def wine_list(request):
wine_list =Wine.objects.order_by('-name')
context ={'wine_list':wine_list}
return render(request, 'reviews/wine_list.html',context)
def review_detail(request , review_id):
review = get_object_or_404(Review , pk = review_id)
context = {'review':review}
return render(request,'reviews/review_detail.html',context)
def wine_detail(request , review_id):
wine = get_object_or_404(Wine, pk = wine_id)
context = {'wine':wine}
return render(request,'reviews/wine_detail.html',context)
def add_review(request,wine_id):
wine = get_object_or_404(Wine , pk = wine_id)
form = ReviewForm(request.POST)
if form.is_valid():
rating = form.cleaned_data['rating']
comment = form.cleaned_data['comment']
user_name=form.cleaned_data['user_name']
review =Review()
review.wine = wine
review.user_name = user_name
review.user_name = user_name
review.rating =rating
review.comment = comment
review.pub_date = datetime.datetime.now()
review.save()
return HttpRespponseRedirect(reverse('reviews:wine_detail',args = (wine.id,)))
return render(request,'reviews/wine_detail.html',{'wine':wine,'form':form})`
reviews/urls.py
urlpatterns = [
# ex: /
url(r'^$', views.review_list, name='review_list'),
# ex: /review/5/
url(r'^review/(?P<review_id>[0-9]+)/$', views.review_detail, name='review_detail'),
# ex: /wine/
url(r'^wine$', views.wine_list, name='wine_list'),
# ex: /wine/5/
url(r'^wine/(?P<wine_id>[0-9]+)/$', views.wine_detail, name='wine_detail'),
url(r'^wine/(?P<wine_id>[0-9]+)/add_review/$', views.add_review, name='add_review'),
]
reviews/templates/reviews/base.html
{% block bootstrap3_content %}
<div class="container">
<nav class="navbar navbar-default">
<div class="navbar-header">
<a class="navbar-brand" href="{% url 'review_list' %}">Winerama</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Wine list</li>
<li>Home</li>
</ul>
</div>
</nav>
<h1>{% block title %}(no title){% endblock %}</h1>
{% bootstrap_messages %}
{% block content %}(no content){% endblock %}
</div>
{% endblock %}
THANKS IN ADVANCE.
PLEASE HELP ME FOR THE SAME.
The error is self explanatory:
Somewhere in your template html you have written
{% url 'user_review_list' %}
That means you are calling user_review_list function, but it is not defined in views. Instead you have defined review_list function.

Django No Reverse Match Error

I've been working on this error for the better part of a week and this is the error I keep receiving:
>
NoReverseMatch at /practice/practice/2/saleinfoedit/
Reverse for 'car_detail' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['practice/practice/(?P<pk>\\d)$']
I've simplified the code to what are the relevant parts of the error, I think. The idea is to have a list page of cars and when you click on the car link you can edit the Sale History of the vehicle. Eventually I'll setup formsets for this part, but babysteps. Here's the relevant code:
models.py
class Car(models.Model):
car_name = models.CharField(max_length=200)
color = models.CharField(max_length=200)
age = models.CharField(max_length=200)
def get_absolute_url(self):
return reverse('practice:car_detail',kwargs={'pk':self.pk})
def __str__(self):
return '%s' %(self.car_name)
class SaleInfo(models.Model):
car_name = models.ForeignKey(Car, on_delete=models.CASCADE,)
price = models.CharField(max_length=100)
date = models.CharField(max_length=100)
comments = models.CharField(max_length=200)
def __str__(self):
return '%s' %(self.car_name)
def get_absolute_url(self):
return reverse('practice:car_detail',kwargs={'pk':self.pk})
views.py
class IndexView(generic.ListView):
template_name = 'practice/carlist.html'
context_object_name = 'latest_car_list'
def get_queryset(self):
return Car.objects.all()
class DetailView(generic.DetailView):
model = Car
form_class = CarForm
template_name = 'practice/car_detail.html'
class UpdateView(generic.UpdateView):
model = Car
form_class = CarFormEdit
class SaleInfoUpdateView(generic.UpdateView):
model = SaleInfo
form_class = SaleInfoFormEdit
template_name = 'practice/saleinfo_form.html'
urls.py
app_name = 'practice'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'), # shows lists of Cars via Car Name
url(r'^practice/(?P<pk>\d)$', views.DetailView.as_view(), name='car_detail'),
url(r'^practice/(?P<pk>\d)/edit/$', views.UpdateView.as_view(), name='car_edit'),
url(r'^practice/(?P<pk>\d)/saleinfoedit/$', views.SaleInfoUpdateView.as_view(), name='saleinfo_edit'),
]
car_detail.html
{% extends 'practice/car_base.html' %}
{% block post_content %}
<div class="col-md-8">
<a class='btn btn-primary' href="{% url 'practice:car_edit' pk=car.pk %}">
<span class='glyphicon glyphicon-pencil'></span>
</a>
<p>{{ car.car_name|safe }}</p>
<p>{{ car.color|safe }} {{ car.age|safe }} </p>
<a class='btn btn-primary' href="{% url 'practice:saleinfo_edit' pk=car.pk %}">
<span class='glyphicon glyphicon-pencil'> SaleInfo</span>
</a>
</div>
{% endblock %}
saleinfo_form.html
{% extends 'practice/car_base.html' %}
{% block post_content %}
{% load bootstrap3 %}
<form class="" action="" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<!-- {{form.as_p}} -->
<input type="submit" name="" value="Update">
</form>
{% endblock %}
I can post my templates too if necessary. I'm sure it's something simple I keep looking past, but after a few days I'm lost.
According to the error message, the parameter pk you have given to the {% url %} tag is empty:
...with keyword arguments '{'pk': ''}'
There are two common reasons for that:
You have a typo in your variable name in your template.
You are creating a new object, so it doesn't have an ID/PK yet.
Your templates look fine though, so here is how I would debug it:
Remove {% url %} tags one after the other until you find the actual culprit.
Print out the variable you pass as keyword argument pk.
One more thing: \d matches exactly one digit, so your URL patterns will stop working once you have more than 9 cars. You have to add a + to match one or more digits:
url(r'^practice/(?P<pk>\d+)/edit/$', views.UpdateView.as_view(), name='car_edit'),
Also, like #wencakisa remarked, URLs in Django usually end with a slash, but that isn't mandatory.
Edit: I just noticed two more things:
your SaleInfo.get_absolute_url method uses practice:car_detail. Shouldn't that be saleinfo_edit?
in the car_detail.html template, you use {% url 'practice:saleinfo_edit' pk=car.pk %}. That won't work. If there is only one SaleInfo per car, use a OneToOneField instead of a ForeignKey in your model. Then you can do something like:
{% if car.sale_info %}
{% url 'practice:saleinfo_edit' pk=car.sale_info.pk %}
{% endif %}