no match for queryset in UpdateView - python

The queryset in my view dont send back any result, however when Im executing the raw SQL command with DB Browser for example I have the result I want, I dont understnad why my queryset dont send back anything...
I got a 404 Not Found - No soldier to list found matching the query
the view:
class EditUnitsToListUpdateView(UpdateView):
model = SoldierToList
fields = ('soldier', 'list', 'author')
template_name = 'armybuilder_edit_unit_to_list.html'
def get_queryset(self):
print (self.model.objects.filter(list=54).query)
return self.model.objects.filter(list=54)
My models:
class List(models.Model):
faction = models.ForeignKey(Faction, on_delete=models.CASCADE)
title = models.CharField(max_length=30)
format_points = models.IntegerField()
description = models.CharField(max_length=30)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("home")
class Soldier(models.Model):
title = models.CharField(max_length=30)
picture = models.FileField(blank=True,)
points = models.IntegerField()
factions = models.ManyToManyField(Faction)
def __str__(self):
return self.title
class SoldierToList(models.Model):
soldier = models.ForeignKey(Soldier, on_delete=models.CASCADE,)
list = models.ForeignKey(List, on_delete=models.CASCADE,)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
My urls:
path('list/own/<int:list_id>/<int:faction_id>/addunit', AddUnitsToListFormView.as_view(), name='add_unit_to_list'),
path('list/own/<int:pk>/<int:faction_id>/editlist/toto', EditUnitsToListUpdateView.as_view(), name='edit_unit_to_list'),
The raw sql that work when executed separatly:
SELECT "armybuilder_soldiertolist"."id", "armybuilder_soldiertolist"."soldier_id", "armybuilder_soldiertolist"."list_id", "armybuilder_soldiertolist"."author_id" FROM "armybuilder_soldiertolist" WHERE "armybuilder_soldiertolist"."list_id" = 54
Thanks for your help guys and have a great day !

Related

Django, generic view dynamic filtering

i'm starting out with Django and trying to render all Shows(screenings) that selected Movie had. Here's the code:
url
path('movie/<int:pk>/', MovieDetails.as_view(), name='movie'),
Models
class Movie(models.Model):
title = models.CharField(max_length=200)
description = models.CharField(max_length=255, blank=True)
def __str__(self):
return f'{self.title}'
class Show(models.Model):
show_date = models.DateField()
start_time = models.TimeField()
movie = models.ForeignKey(Movie, on_delete=models.CASCADE, null=True, blank=True)
city = models.ForeignKey(City, on_delete=models.CASCADE, null=True, blank=True)
title = models.CharField(max_length=200, blank=True)
def __str__(self):
return f'{self.show_date}'
View
class MovieDetails(DetailView):
model = Movie
context_object_name = 'movie'
def get_queryset(self):
self.movie = get_object_or_404(Movie, id=self.kwargs['pk']) #find movie by id from url
shows_played = Show.objects.filter(movie=self.movie)
print(shows_played) #prints out some shows
return shows_played
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['shows_played'] = Show.objects.filter(movie=self.movie)
return context
The shows_played prints out some shows, so it seems like everything is fine but when the url: /movies/1
is called I get a 404, No show found matching the query rendered in browser and
Not Found: /movie/1/ printed in console
What am i doing wrong?
Thank you
I figured it out. My mistake was that i was using DetailView instead of ListView(which has get_queryset method) for "MovieDetails".

filter on category in django

I was doing the project on Django & react using RestAPI to get into it more deeply. I have a problem with the view part. There are models; Course, CourseCategory.
CourseCategory is about what category a course is related to (which is ForeignKey).
I have list all the courses in one page where a certain category is clicked. But I don't know how to do it in the right way.
Here is my model
class CourseCategory(models.Model):
title = models.CharField(max_length=150)
description = models.TextField()
def __str__(self):
return self.title
class Course(models.Model):
category = models.ForeignKey(CourseCategory, on_delete=models.CASCADE, null=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=100, null=False , blank= False)
brief = models.TextField(null=False , blank= False)
image = models.ImageField(upload_to='img/%y/m/%d', default='img/1.png')
def __str__(self):
return self.name
and here is my view where i tried to write a filter function
class CourseList(generics.ListCreateAPIView):
queryset = Course.objects.all()
serializer_class = CourseSerializer
#permission_classes = [IsAuthenticated]
#authentication_classes = [TokenAuthentication]
def get_queryset2(self):
qs = super().get_queryset()
if 'result' in self.request.GET:
cat = int(self.request.GET['result'])
qs = Course.objects.filter( category=cat )
return qs
when tried to test that by writing the id of the category it's doesn't work like this
enter image description here
enter image description here
so is there anyone who can help, please

Django generic create view . Can we add conditions to save data from the form?

This is what my code looks like and I want to add some condition to the Borrower create view like if the stock method of book returns 0 then don't list that book in field while creating a new borrower or if it isn't possible at least throw some error while adding borrower to that book.
models.py:
class Book(models.Model):
id = models.UUIDField(primary_key=True, unique=True,
default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
summary = models.TextField(
max_length=1000, help_text="Enter a brief description of the book")
isbn = models.CharField('ISBN', max_length=13,
help_text='13 Character https://www.isbn-international.org/content/what-isbn')
genre = models.ManyToManyField(
Genre, help_text="Select a genre for this book")
language = models.ForeignKey(
'Language', on_delete=models.SET_NULL, null=True)
total_copies = models.IntegerField()
pic = models.ImageField(blank=True, null=True, upload_to='books')
def stock(self):
total_copies = self.total_copies
available_copies = total_copies - \
Borrower.objects.filter(book=self).count()
if available_copies > 0:
return available_copies
else:
return 0
def __str__(self):
return self.title
class Borrower(models.Model):
id = models.UUIDField(primary_key=True, unique=True,
default=uuid.uuid4, editable=False)
student = models.ForeignKey('Account', on_delete=models.CASCADE)
book = models.ForeignKey('Book', on_delete=models.CASCADE)
issue_date = models.DateField(
null=True, blank=True, help_text='YYYY-MM-DD', default=date.today)
return_date = models.DateField(
null=True, blank=True, help_text='YYYY-MM-DD')
def __str__(self):
return self.student.name.title()+" borrowed "+self.book.title.title()
def fine(self):
today = date.today()
fine = 0
if self.return_date <= today:
fine += 5 * (today - self.return_date).days
return fine
views.py:
class BorrowerView(LoginRequiredMixin, ListView):
model=Borrower
context_object_name='borrowers'
template_name = 'library/borrower_list.html'
def get_context_data(self, **kwargs):
context=super().get_context_data(**kwargs)
if self.request.user.is_admin or self.request.user.is_superuser:
context['borrowers']=context['borrowers']
else:
context['borrowers']=context['borrowers'].filter(student = self.request.user.id)
return context
class BorrowerCreate(LoginRequiredMixin, UserAccessMixin, CreateView):
model=Borrower
permission_required= 'borrowers.add_borrowers'
fields='__all__'
success_url=reverse_lazy('library:borrower-list')
def form_valid(self, form):
form.instance.user=self.request.user
return super(BorrowerCreate, self).form_valid(form)
class BorrowerDetail(LoginRequiredMixin, DetailView):
model=Borrower()
context_object_name='borrower'
template_name='library/borrower.html'
class Book(models.Model):
id = models.UUIDField(primary_key=True, unique=True,
default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
summary = models.TextField(
max_length=1000, help_text="Enter a brief description of the book")
isbn = models.CharField('ISBN', max_length=13,
help_text='13 Character https://www.isbn-international.org/content/what-isbn')
genre = models.ManyToManyField(
Genre, help_text="Select a genre for this book")
language = models.ForeignKey(
'Language', on_delete=models.SET_NULL, null=True)
total_copies = models.IntegerField()
pic = models.ImageField(blank=True, null=True, upload_to='books')
#new, use this to keep track of available books
available_copies = models.IntegerField()
def __str__(self):
return self.title
When any borrower borrows a copy of the book, you will subtract it from the total copies.
class BorrowerCreate(LoginRequiredMixin, UserAccessMixin, CreateView):
model=Borrower
permission_required= 'borrowers.add_borrowers'
fields='__all__'
success_url=reverse_lazy('library:borrower-list')
#remember to get the object using slug or 404
def form_valid(self, form):
instance = form.save(commit=False)
instance.user = self.request.user
book = Book.objects.get(id=instance.book.id)
#get the book id from the form and check if the book is still available, then subtract.
if book.available_copies > 0:
book.available_copies -= 1
book.save()
instance.save()
message.success(self.request, _("successful")
message.error(self.request, _("Book not in stock")
return super(BorrowerCreate, self).form_valid(form)
If user return the book and click returned. you can perform a similar action by adding to available copies.
This is not the solution, you can write a fat model with methods that takes care of both borrowing and return. Like this
def borrow(self):
self.available_copies -= 1
def returned(self):
self.available_copies += 1
You can call these two methods in different views or define a signal that call them using pre_save
Ist:
Instead of defining a new method which you called stock, why not add stock as a field instead of making a database query.
2nd:
calling the class inside the same class is not the best way to make queries inside the class.
3rd:
To add a condition while adding an object, you need to override the save method of the object like this.
def save(self, *args, **kwargs):
# do_something() here.....
# then
return super().save(*args, **kwargs)
The above code will enable you to perform any action before saving the object.
Another way you can do this is inside the form_valid function like this.
def form_valid(self, form):
instance = form.save(commit=False)
# commit = False will make sure that the form is not saved
# then you can now query the database and check conditions like
if Borrower.object.all().count() > 0:
instance.save()
messages.success(self.request, _("saved successfully")
else:
messages.error(self.request, _("Error")
return redirect("URL")

Error 'Product' object has no attribute '_combinator_query'

I am creating an e-commerce website in django where the homepage can be changed dynamically by changing the instances of FeaturedProduct objects. These objects have two ForeignKeys. First is to the Product class and the other is to FeaturedCategory class(this is for the type of deal, eg: daily deals, new arrivals, etc). So, I'm trying to get the Product instances in a queryset instead of the FeaturedProduct queryset. When I union two querysets, I get an error that 'Product' object has no attribute '_combinator_query'. The codes have been shown below.
My models.py
class Product(models.Model):
product_id = models.AutoField
product_name = models.CharField(max_length=50, unique=True)
category = models.ForeignKey(Category, on_delete=models.SET_DEFAULT, default='1')
sub_category = models.ForeignKey(SubCategory, on_delete=models.SET_DEFAULT, default='2')
price = models.IntegerField(default=0)
stock = models.IntegerField(default=0)
desc = models.TextField()
pub_date = models.DateField()
avg_rating = models.IntegerField(default=0)
avg_rating_float = models.FloatField(default=0.0)
number_of_ratings = models.IntegerField(default=0)
image1 = models.ImageField(upload_to="images", default="")
image2 = models.ImageField(upload_to="images", default="")
image3 = models.ImageField(upload_to="images", default="")
slug = models.SlugField(blank=True, help_text=('Leave this parameter empty, it will get generated automatically.'))
def save(self, *args, **kwargs):
self.slug = slugify(self.product_name)
super(Product, self).save(*args, **kwargs)
def __str__(self):
return self.product_name
class FeaturedCategory(models.Model):
category = models.CharField(max_length=100)
def __str__(self):
return self.category
class Meta:
verbose_name_plural = "Featured Categories"
class FeaturedProduct(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
featured_category = models.ForeignKey(FeaturedCategory, on_delete=models.CASCADE)
def __str__(self):
return self.product.product_name
My views.py
def index(request):
prod = Product.objects.none()
feat = FeaturedProduct.objects.all()
for pro in feat:
ob = Product.objects.get(product_name=pro.product)
print(ob.product_name)
print(ob.category)
print(ob.sub_category)
print(ob.price)
prod.union(ob) # Error found here
# Working part
products = Product.objects.all()
context = {'products': products}
return render(request, 'index.html', context)
The last three lines are working fine, but not the other part of the index function.
Please help. Thank You.

AttributeError; Dynamic url for list of charts by category issue (queryset filter)

Django 'CategorisedListView' object has no attribute 'slug' or Page not found (error 404) issue
I'm on Django 2.0, using generic class list view. I have tried dynamic url based on slug and queryset filter on slug to get list of charts by category.
Please help! I've been stuck here for a couple of days since.
views.py
class CategoriesView(generic.ListView):
template_name = 'Bokeh/categories.html'
context_object_name = 'all_categories'
def get_queryset(self):
return Category.objects.all()
class CategorisedListView(generic.ListView):
model = Category
template_name = 'categories/list_of_charts_by_category.html'
context_object_name = 'categorised'
def get_queryset(self):
self.category = get_object_or_404(Category, name = self.kwargs['slug'])
return Chart.objects.filter(category=self.slug)
models.py
class Category(models.Model):
name = models.CharField(max_length=100)
image_file = models.ImageField(default=None, unique=True)
slug = models.SlugField(max_length=100, unique=True)
parent = models.ForeignKey('self', on_delete=models.PROTECT, blank=True, null=True, related_name='children')
def __str__(self):
return self.name
def get_absolute_url(self):
return '{slug}/'.format(slug=self.slug)
class Meta:
ordering = ('name',)
verbose_name = 'Category'
verbose_name_plural = 'Categories'
class Chart(models.Model):
name = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique=True)
description = models.TextField(max_length=250)
url = models.URLField(default=None, blank=True)
embed_url = models.TextField(default=None, blank=True)
image_file = models.ImageField(default=None, unique=True)
code_file = models.FileField(default=None, blank=True, unique=True)
chart_library = models.CharField(max_length=250)
author = models.ForeignKey(User, on_delete=models.CASCADE, default=1)
tag = TaggableManager()
category = models.ForeignKey(Category, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.name + ' - ' + self.chart_library
def get_absolute_url(self):
return reverse('Bokeh:detail', kwargs={'pk': self.pk})
def read_file(self):
data = self.code_file.path
with open(self.code_file.path, 'r', encoding='UTF-8') as data:
content = data.read()
return content
class Meta:
ordering = ('name',)
urls.py
path("categories/", views.CategoriesView.as_view(), name='categories'),
# /Bokeh/categories/<category_slug>
path("categories/<slug:slug>/", views.CategorisedListView.as_view(), name='list_of_charts_by_category'),
it is supposed to query the database when a specific category is clicked and return the list of charts categorised under that specific category. However, the page throws 'CategorisedListView' object has no attribute 'slug'
The lookup you're doing in get_queryset() isn't quite right. Firstly, you seem to be looking up the Category by name rather than by the slug. Then you try and filter the Charts using their category attribute, but instead of passing the category you pass a non-existent attribute self.slug.
Try changing the implementation to this:
def get_queryset(self):
# Lookup the Category using it's slug attribute, not name, and assign to local variable
category = get_object_or_404(Category, slug=self.kwargs['slug'])
# Now lookup the Charts using the category we just looked up
return Chart.objects.filter(category=category)

Categories