Get Absolute Url keeps directing to one particular id - python

Good day, I have a Django project where I want to display an order list and detail. All seems to work perfectly but the link only links to one particular id ( for instance id 66). I have tried deleting the particular order id from the admin panel, thinking maybe the URL would just reset, but I get the URL id incremented, now it's no longer id 66 but 67. Pls how can I fix this? here are my codes:
models.py
class Order(models.Model):
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField()
address = models.CharField(max_length=250)
phone_number = models.CharField(max_length=20)
city = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
braintree_id = models.CharField(max_length=150, blank=True)
coupon = models.ForeignKey(Coupon, related_name='orders', null=True, blank=True, on_delete=models.SET_NULL)
discount = models.IntegerField(default=0, validators=[
MinValueValidator(0),
MaxValueValidator(100)
])
class Meta:
ordering = ('-created',)
def __str__(self):
return self.first_name
def get_absolute_url(self):
return reverse('orders:orderdetail', args=[self.id])
views.py
def order_list(request):
orders = Order.objects.all()
current_user = request.user
success = Order.objects.filter(user=current_user.id).filter(paid=True)
fail = Order.objects.filter(user=current_user.id).filter(paid=False)
return render(request, 'orders/order/order_list.html', {
'success': success,
'fail': fail,
'current_user': current_user,
'orders':orders,
})
def order_detail(request, order_id):
order = get_object_or_404(Order, id=order_id)
return render(request, 'orders/order/order_detail.html', {'order': order})
urls.py
from django.urls import path
from . import views
app_name = 'orders'
urlpatterns = [
path('create/', views.order_create, name='order_create'),
path('admin/order/<int:order_id>/', views.admin_order_detail, name='admin_order_detail'),
path('admin/order/<int:order_id>/pdf/', views.admin_order_pdf, name='admin_order_pdf'),
path('addtocart/<int:id>', views.addtocart, name='addtocart'),
path('myorder/', views.order_list, name='orderlist'),
path('myorder/detail/<int:order_id>/', views.order_detail, name='orderdetail'),
]
html
{% for order in orders %}
<a href="{{ order.get_absolute_url }}" style="position: absolute; top: 5px; right: 5px;">
View Details
</a>
{% endfor %}
full html
<div class="col-md-9">
{% for od in success %}
<div class="card mb-3" style="max-width: 540px;">
<div class="row no-gutters">
<div class="col-md-3">
<img alt="product img" class="card-img" src="...">
</div>
<div class="col-md-9">
<div class="card-body" style="position: relative;">
<h5 class="card-title">Product {{ od.id }}</h5>
{% for order in orders %}
<a href="{{ order.get_absolute_url }}" style="position: absolute; top: 5px; right: 5px;">
View Details
</a>
{% endfor %}
<p class="card-text">
<mark style="color: whitesmoke; background-color: brown;border-radius: 3px;font-weight: bold;">{{transaction}}</mark>
</p>
<p class="card-text"><small class="text-muted">Delivered at
{{od.reference_id}}</small></p>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
The URL I get is like this /orders/myorder/detail/66/
I'm gonna add pictures to make it less abstract
Thanks.

Just like #EricMartin said, it was the context of the order
I realized I had {% for od in success %} and {% for order in orders %}
I guess they're not on good terms with each other and since orders is in success, I removed the {% for order in orders %} loop and all seems peaceful again :)

Related

Django - get objects from one table who belong to another objects in other table

I have a project to do which consists to creating a note manager in Django. So I created my tables in sql with foreign keys. And I have been facing a problem for several days. I have a page that lists all the students in the database, and I would like by clicking on a link, to be able to display all the notes belonging to each student.
Here's my SQL tables (étudiants = students / Notes = grades) :
sql students table /
sql grade table
models.py :
class Etudiants(models.Model):
numeroetudiant = models.BigIntegerField(db_column='numeroEtudiant', blank=True, null=True) # Field name made lowercase.
nom = models.CharField(max_length=255, blank=True, null=True)
prenom = models.CharField(max_length=255, blank=True, null=True)
groupe = models.BigIntegerField(blank=True, null=True)
photo = models.TextField(blank=True, null=True)
email = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'etudiants'
def __str__(self):
return self.nom + " " + self.prenom
class Notes(models.Model):
examens = models.ForeignKey(Examens, models.DO_NOTHING, db_column='examens', blank=True, null=True)
etudiant = models.ForeignKey(Etudiants, models.DO_NOTHING, db_column='etudiant', blank=True, null=True)
note = models.BigIntegerField(blank=True, null=True)
appreciation = models.TextField(blank=True, null=True)
class Meta:
managed = False
db_table = 'notes'
def __str__(self):
return "Note de " + self.etudiant.nom + " " + self.etudiant.prenom + " à l'examen de " + self.examens.titre
views.py :
def etudiants(request):
etudiants = Etudiants.objects.all()
return render(request, 'etudiants.html', {'etudiants': etudiants, 'notes': notes})
def affichenote(request, id):
notes = Notes.objects.all()
return render(request, 'affichenote.html', {'notes': notes})
urls.py :
path('etudiants/', views.etudiants, name='etudiants'),
path('affichenote/<int:id>/', views.affichenote, name='affiche-note'),
etudiants.html :
{% extends 'base.html' %} {% block content %}
<div class="row">
{% for Etudiants in etudiants %}
<div class="col-sm-4">
<div class="card">
<img src="..." class="card-img-top" alt="..." />
<div class="card-body">
<h5 class="card-title">{{ Etudiants.nom }} {{ Etudiants.prenom }} </h5>
<p class="card-text">
E-mail : {{ Etudiants.email }} <br>
Numéro étudiant : {{ Etudiants.numeroetudiant }} <br>
Groupe : {{ Etudiants.groupe }} <br>
</p>
Voir les notes
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
If you want by clicking on a link, you would be able to display all the notes belonging to each student. So you can apply filter() through student id in the following way:
views.py
def etudiants(request):
etudiants = Etudiants.objects.all()
return render(request, 'etudiants.html', {'etudiants': etudiants})
def affichenote(request, id):
notes = Notes.objects.filter(etudiant__id=id)
return render(request, 'affichenote.html', {'notes': notes})
urls.py
urlpatterns = [
path('etudiants/', views.etudiants, name='etudiants'),
path('affichenote/<int:id>/', views.affichenote, name='affichenote'),
]
etudiants.html
<div class="row">
{% for etudiant in etudiants %}
<div class="col-sm-4">
<div class="card">
<img src="..." class="card-img-top" alt="..." />
<div class="card-body">
<h5 class="card-title">{{ etudiant.nom }} {{ etudiant.prenom }} </h5>
<p class="card-text">
E-mail : {{ etudiant.email }} <br>
Numéro étudiant : {{ etudiant.numeroetudiant }} <br>
Groupe : {{ etudiant.groupe }} <br>
</p>
Voir les notes
</div>
</div>
</div>
{% endfor %}
</div>
Then, in affichenote.html, you can access all notes, relating to a student.
affichenote.html
<body>
{% for note in notes %}
<p>{{note.edudiant}}</p>
<p>{{note.note}}</p>
<p>{{note.appreciation}}</p>
{% endfor %}
</body>
Note: Models in django generally written in singular form, it will be better if you name it Etudiant and Note instead of Etudiants and Notes respectively, as s is already itself added as the suffix for every model.

Django Query.get raising Object matching query does not exist Error with Try & except as well

models.py
class Inventory(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE,blank=True)
product = models.ManyToManyField(Product, blank=True)
class Product(models.Model):
name = models.CharField(max_length=50)
description = models.TextField(default='Hidden')
image = models.ImageField(upload_to='images/', blank=True, null=True)
interest = models.IntegerField(default=0, blank=True)
price = models.IntegerField(default=0, blank=True)
capital = models.IntegerField(default=1, blank=True)
years = models.IntegerField(default=0, blank=True)
created_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
views.py
def inventory(request):
b = request.user.id # user_id=12
inv1 = Inventory.objects.all()
try:
userdb = inv1.get(user_id__exact=b)
inv1.get(user_id__exact=b)
context = {}
return render(request, 'redcube/inventory.html', context)
except:
userdb = inv1.get(user_id__exact=b)
products = userdb.product.all()
bal = 0
for p in products:
print(p.price, '=p.price')
bal = bal + p.price
context = {'inv1': inv1, 'userdb': userdb, 'products': products, 'bal': bal}
return render(request, 'redcube/inventory.html', context)
context = {'inv1':inv1}
return render(request, 'redcube/inventory.html', context)
inventory.html
{% extends 'basic.html' %}
{% load static %}
{% block content %}
<link href="{% static 'bootstrap.min.css' %}" rel="stylesheet">
<style>
.center {
margin: auto;
width: 50%;
padding: 10px;
}
</style>
<div class = "w-100 p-auto" style = "width:500px; margin: 0 auto;">
<div class="center">
<div class="container">
<div class="card" style="width: 50rem;">
<div class="center">
<div class = "text-center user-block">
<h1 class="center">Inventory</h1>
{% if products %}
<h2>Balance <span class="text-info">{{bal}}</span> Tcoins </h2>
{% else %}
<h2 class="text-danger">No items</h2>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{% csrf_token %}
{% if user.is_authenticated %}
{% for p in products %}
<div class = "w-100 p-auto" style = "width:500px; margin: 0 auto;">
<div class="center">
<div class="container">
<div class="card" style="width: 50rem;">
<div class="center">
<div class = "text-center user-block">
<h3 class = "text-info left-things">{{p.name}}</h3>
<p><h5> {{p.price}} Tcoin </h5> Description {{p.description}}</p>
<img class="w-10 p-auto" src = "{{p.image.url}}" alt = "User Image" style = "width :400px; height:auto; margin: 0 auto;">
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
{% endif %}
<div class="container">
{% endblock %}
When the Inventory objects has no db about the b(user_id=12)
(The user is not yet make the product so Inventory DB does not have the used_id=12)
inventory.html page shows me the 'DoesNotExist error' on
userdb = inv1.get(user_id__exact=b)
I'm new to django, I know that I can make the if option to avoid on the html page, but I want to know about views.py side option to avoid the DoesNotExits error solution.
I've tried to find the answer but could not for hours so
how can I fix this problem? :{

Basic Django POST not creating model with sqlite

When I click the submit button, it redirects me to the create model (in this case create record) page, and does not actually create a new model, it doesn't appear in the main page which shows all models that were created.
I tried following this tutorial: Link
I feel like I did mostly the same things as him, and yet my form submission button does not create my post. The differences between our programs is simply the naming and the number of fields in my model.
The user registration form works, but that is using a function based view, this is using a class based view (should still work as far as I know), and there are barely any differences between the model creation html and the user registration html.
Here's the model creation form, record_form.html:
{% extends "catalog/base.html" %}
{% block content %}
<h1 class="text py-3 pt-4">Create a Record!</h1>
<style>
.text {
font-size: 40px;
font-weight: bold;
color: #060007;
}
</style>
<div class="shadow p-3 mb-3 bg-light rounded">
<form class="form" method="POST" action="/catalog/">
{% csrf_token %}
<p>
<label for="name">Name:</label>
{{ form.name }}
</p>
<p>
<label for="description">Description:</label>
</p>
<p>
{{ form.description }}
</p>
<p>
<label for="date_start">Date start:</label>
{{ form.date_start }}
</p>
<p>
<label for="date_end">Date end:</label>
{{ form.date_end }}
</p>
<p>
<label for="manufacturer">Manufacturer:</label>
{{ form.manufacturer }}
</select>
</p>
<p>
<label for="condition_rating">Condition rating (between 0 and 5):</label>
{{ form.condition_rating }}
</p>
<p>
<label for="condition_description">Condition description:</label>
</p>
<p>
{{ form.condition_description }}
</p>
<div>
<input type="submit" name="Create Record" value="Create Record" class="submit action-button">
</div>
</form>
<style>
.form {
color: #060007;
}
</style>
</div>
{% endblock content %}
Here's my models that the program is using in models.py:
class CommonInfo(models.Model):
id = models.AutoField(primary_key=True) # not necessary as django adds this to every model, but declared so that it is clear
creation_date = models.DateField(auto_now_add=True)
last_modified = models.DateField(auto_now=True)
name = models.CharField(max_length=100, help_text='Enter name')
description = models.TextField(blank=True, help_text='Enter description')
class Meta:
abstract = True
ordering = ['-last_modified', 'name'] # '-' reverses order, e.i. newest first
# ordering = ['name','-last_modified'] # '-' reverses order, e.i. newest first
class Catalog(CommonInfo):
def get_absolute_url(self):
return reverse('catalog-detail', args=[str(self.id)])
def __str__(self):
return f'{self.name}'
class Record(CommonInfo):
my_catalog = models.ForeignKey(Catalog, on_delete=models.CASCADE) # Many records to one Catalog. Deletes all records associated with deleted catalog.
date_start = models.DateField() # TODO - is date range for when aquired or creation?
date_end = models.DateField()
manufacturer = models.ForeignKey('Manufacturer', null=True, blank=True, on_delete=SET_NULL)
condition_rating = DecimalField(
help_text='Enter condition rating from 0 to 5',
default=0,
decimal_places=2,
max_digits=3,
validators=[MinValueValidator(Decimal('0')), MaxValueValidator(Decimal('5'))]
)
condition_description = models.TextField(blank=True, help_text='Enter condition description')
def get_absolute_url(self):
return reverse('record-detail', args=[str(self.id)])
def __str__(self):
return f'{self.name} ({self.my_catalog})'
Here's the CreateView class in views.py:
class RecordCreateView(CreateView):
model = Record
fields = ['name', 'description', 'date_start', 'date_end', 'manufacturer', 'condition_rating', 'condition_description'] #Owner/nation/continent not able to be done, since provenance is not linked to Record
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
Here's urls.py:
from django.urls import path
from .views import RecordDetailView, RecordCreateView
from . import views
from django.views.generic import RedirectView
urlpatterns = [
path('about/', views.about, name='catalog-about'),
path('home/', views.home, name='catalog-home'),
path('catalog/', views.catalogList, name='catalog-list'),
path('', RedirectView.as_view(url='about/', permanent=True)),
path('login/', views.loginPage, name='catalog-login'),
path('logout/', views.logoutUser, name='catalog-logout'),
path('register/', views.register, name='catalog-register'),
path('record/<int:pk>/', RecordDetailView.as_view(), name='record-detail'),
path('record/new/', RecordCreateView.as_view(), name='record-create'),
]
i dont see a field "name" on Recored table and you don't give the catalog on your RecordCreateView.

I'm new to Django and I'm having trouble displaying categories in this website

Models.py
class Listing(models.Model):
title = models.CharField(max_length=64, default="")
bid = models.ForeignKey(Bid, on_delete=models.CASCADE, related_name="listing", default=None,)
description = models.TextField(default="")
image_url = models.CharField(max_length=200, default="")
date = models.DateTimeField(default=timezone.now)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="listings", default="")
is_closed = models.BooleanField(default=False, blank=True, null=True)
watchlist = models.ManyToManyField(User, blank=True, related_name="watching")
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="listing", null=False, blank=True, default="")
def __str__(self):
return self.title
#the category class
class Category(models.Model):
category = models.CharField(max_length=64)
def __str__(self):
return self.category
Views.py
*This is where I think the problem is because i'm not very familiar with the methods, if I use category = request.POST["category], I get an error saying multivalue dict..., I'm just stuck here if you have a clue how i can modify this method to show the items in a category *
def categories(request):
category = request.POST("category")
listings = category.listings.all()
return render(request, "auctions/categories.html", { "listings":listings })
```
categories.html
{% extends "auctions/layout.html" %}
{% block body %}
<h2>Categories</h2>
<form action="{% url 'categories' %}" method="post">
<div class="form-group">
<label for="categories">Category</label>
<select class="form-control" name="categories" id="categories">
{% for category in categories %}
<option>{{category}}</option>
{% endfor %}
</select>
</div>
</form>
{% for listing in listings %}
{% if not listing.is_closed or user == listing.bid.user %}
<p></p>
<div class="card" style="width: 60rem;">
<img class="card-img-top" style="width: 20rem;" src="{{listing.image_url}}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{listing.title}}</h5>
<p class="card-text">{{listing.description}}</p>
<p>Bid: {{listing.bid}}</p>
<p>Created {{listing.date}}</p>
</div>
<div class="card-body">
More
</div>
</div>
<p></p>
{% endif %}
{% endfor %}
{% endblock %}
You're not receiving anything as POST, so there wouldn't be any value there.
Your lines of:
category = request.POST("category")
listings = category.listings.all()
make no sense because:
in category = request.POST("category") you are first trying to store something into category from the POST which #1 doesn't exist and #2 would be a string even if it did.
Let's just assume there is something in the POST with the key "category", you then try to receive all the listings using the category variable. Since you didn't define category variable properly, there's no way this would work anyways. Assuming for one second that you had, the Category object you defined in your models has no listings field or relation.
The correct way to do this would be:
category = Category.objects.get(category="Name Of Category You Set")
listings = Listing.objects.filter(category=category)
But before you go ahead and do anything, I really recommend you learn more about Objects and classes because seeing your above attempts you seem to lack knowledge of not only those but of variables swell.

Cannot resolve NoReverseMatch at / error in Django

I am trying to make an auction website (for a project). And we need to have an option to add each product to the "watchlist". However, I keep getting error when clicking on "watchlist" button. This is in Python using Django.
This is the exact error I'm getting:
NoReverseMatch at /viewlisting/3/addwatchlist
Reverse for 'addwatchlist' with arguments '('',)' not found. 1 pattern(s) tried: ['viewlisting/(?P<listing_id>[0-9]+)/addwatchlist$']
Here is a summary of my code:
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
path("register", views.register, name="register"),
path("create_listing", views.create_listing, name="create_listing"),
path("viewlisting/<int:listing_id>", views.viewlisting, name="viewlisting"),
path("viewlisting/<int:listing_id>/addwatchlist", views.addwatchlist, name="addwatchlist")
]
views.py:
def viewlisting(request,listing_id):
productname= listings.objects.get(id=listing_id)
name= productname.name
description = productname.description
image = productname.image
price= productname.price
seller = productname.seller
category = productname.category
date = productname.date
productid= productname.id
return render(request, "auctions/viewlisting.html",{
"name":name,
"description":description,
"image":image,
"price":price,
"seller":seller,
"category":category,
"date":date,
"id":productid
})
def addwatchlist(request,listing_id):
if request.method == "POST":
item_exists= watchlist.objects.filter(
id = listing_id, user= request.user.username
)
if item_exists:
show_watchlist = watchlist.objects.all()
exist_alert= "This item already exists in your watchlist!"
return render(request,"auctions/viewlisting.html",{
"alert":exist_alert,
"show_watchlist":show_watchlist
})
else:
new_item = watchlist()
new_item.user = request.user.username
new_item.listing = listings.objects.get(id=listing_id).name
new_item.save()
success_alert = "This item was added to your watchlist!"
show_watchlist = watchlist.objects.all()
return render(request,"auctions/viewlisting.html",{
"alert": success_alert,
"show_watchlist":show_watchlist,
})
else:
return render(request,"auctions/viewlisting.html")
And this is my viewlisting html page which renders different product detials and allows the user to add the product to their watchlist.
viewlisting.html:
{% extends "auctions/layout.html" %}
{% block body%}
<div class="container-fluid">
<div class="row">
<div class="col-md-4"><img src={{image}} style="max-width: 350px;"></div>
<div class="col-md-4"><strong>{{ name }}</strong><br> {{description}}
</div>
<div class="col-md-4">
<strong>Current Price:</strong> <sup>CAD$</sup>{{price}}
<br>
<strong>Category:</strong> {{ category }}
<br>
<br>
<form action="{% url 'addwatchlist' id %}" method="POST">
{% csrf_token %}
<button style="color:ghostwhite" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Add to Watchlist
</button>
</form>
</div>
</div>
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">{{alert}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<h6>Your Watchlist:</h6>
{% for i in show_watchlist %}
<li>{{i.listing}</li>
{% endfor %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
And this is models.py:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
def __str__ (self):
return f"username:{self.username}, email:{self.email}, password:{self.password}"
class listings(models.Model):
name = models.CharField(max_length=70, null= True, unique=True)
seller = models.CharField(max_length=100)
price = models.IntegerField(null= True)
category = models.CharField(max_length=100, null=True)
date = models.DateTimeField(auto_now=True)
description= models.CharField(max_length=500)
image= models.URLField()
def __str__ (self):
return f"{self.name} by {self.seller}: {self.price}, {self.category}, {self.date}, {self.description}, {self.date}, {self.image} "
class bids(models.Model):
bidder = models.ForeignKey(User, on_delete= models.CASCADE, related_name="bidder", null=True)
bid_price = models.IntegerField(null= True)
product= models.ForeignKey(listings, on_delete= models.CASCADE, to_field= "name", null=True)
bid_date = models.DateTimeField(auto_now=True, null=True)
def __str__(self):
return f"{self.bidder} bid {self.bid_price} on {self.product}: posted on {self.bid_date}"
class comments(models.Model):
commenter = models.ForeignKey(User, on_delete= models.CASCADE, related_name="commenter", null=True)
content = models.CharField(max_length=500, null=True)
post_date = models.DateTimeField(auto_now=True)
listing = models.ForeignKey(listings, on_delete= models.CASCADE, to_field= "name",null=True)
def __str__(self):
return f"{self.commenter} commented {self.content} on listing: {self.listing} ({self.post_date})"
class watchlist(models.Model):
user=models.CharField(max_length=500)
listing = models.CharField(max_length=500)
def __str(self):
return f"User: {self.user}, Product: {self.listing}"
I would really appreciate any help or hints.
Also, let me know if you need more explanations.
This is because you are passing id in form url and listing_id in urls.py
change <form action="{% url 'addwatchlist' id %}" method="POST"> to <form action="{% url 'addwatchlist' listing_id=id %}" method="POST">

Categories

Resources