How to get object from previous view(CBV) in Django? - python

I tried to get the object value in CreateView from previous DetailView. But Failed. Is there any simple way to do this?
In this code, how can I replace this '???'(in CreateView) by an album object where album.pk == id according to 'item-add'(url(r'^(?P<id>[0-9]+)/pic/add/$', views.ItemCreate.as_view(), name='item-add'))
models.py
class Album(models.Model):
credit = models.CharField(max_length=250)
album_title = models.CharField(max_length=100)
logo = models.FileField()
def get_absolute_url(self):
return reverse('picture:detail', kwargs={'pk': self.pk})
def __str__(self):
return self.album_title + ' - ' + self.credit
class Item(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(choices=TYPE_CHOICES, max_length=1)
caption = models.CharField(max_length=100)
class Meta:
ordering = ('upload_date', 'caption')
def get_absolute_url(self):
return reverse('picture:item-detail', kwargs={ 'id': self.album_id , 'pk': self.pk})
def __str__(self):
return self.caption
views.py
class DetailView(generic.DetailView):
model = Album
template_name = 'picture/detail.html'
class ItemCreate(CreateView):
model = Item
fields = ['album', 'file_type', 'caption']
def get_initial(self):
album = ???
return {
'album': album,
'file_type': 't',
}
urls.py
urlpatterns = [
# /picture/<album_id>/
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
# /picture/<album_id>/<pic_id>
url(r'^(?P<id>[0-9]+)/(?P<pk>[0-9]+)/$', views.ItemDetailView.as_view(), name='item-detail'),
# /picture/<album_id>/pic/add
url(r'^(?P<id>[0-9]+)/pic/add/$', views.ItemCreate.as_view(), name='item-add'),
]

The primary key is passed as an id URL parameter, so you can access this with self.kwargs:
from django.shortcuts import get_object_or_404
class ItemCreate(CreateView):
model = Item
fields = ['album', 'file_type', 'caption']
def get_initial(self):
album = get_object_or_404(Album, pk=self.kwargs['id'])
return {
'album': album,
'file_type': 't',
}

Related

ImproperlyConfigured. View is missing a QuerySet. Define model, queryset, or override get_queryset()

This is the error i am having :- ImproperlyConfigured at /attendanceattendance/add
AddAttendance is missing a QuerySet. Define AddAttendance.model, AddAttendance.queryset, or
override AddAttendance.get_queryset().
This is my models.py
class StudentAttendance(models.Model):
StudentName = models.CharField(max_length=150)
StudentRoll = models.CharField(max_length=100)
lecturesAttended = models.IntegerField(null=True)
TotalLectures = models.IntegerField(null=True)
slug = models.SlugField(allow_unicode=True,null = True)
def __str__(self):
return self.StudentName
def save(self,*args,**Kwargs):
self.slug = slugify(self.StudentName)
super().save(*args,**Kwargs)
def get_absolute_url(self):
return reverse("home")
class Meta():
ordering = ['StudentName']
This is my view
class AddAttendance(generic.CreateView,LoginRequiredMixin):
form_model = forms.AttendanceForm
success_url = reverse_lazy('home')
template_name = 'attendance/attendance.html'
This is my urls
from django.conf.urls import url
from . import views
app_name = 'attendance'
urlpatterns = [
url(r'^attendance/add',views.AddAttendance.as_view(),name='attend')
]
enter image description here
Your view should look like this
class AddAttendance(generic.CreateView,LoginRequiredMixin):
form = forms.AttendanceForm
model = StudentAttendance
success_url = reverse_lazy('home')
template_name = 'attendance/attendance.html'

How to set initial value of ForeignKey dynamically in CreateView?

I want to set dynamically initial value of ForeignKey in CreateView. But is there any simple way to do this ?
And I tried like this (as answer of this link). But it is not working.
How can I pass the album(ForeignKey) to the field in CreateView?
models.py
class Album(models.Model):
credit = models.CharField(max_length=250)
album_title = models.CharField(max_length=100)
logo = models.FileField()
def get_absolute_url(self):
return reverse('picture:detail', kwargs={'pk': self.pk})
def __str__(self):
return self.album_title + ' - ' + self.credit
class Item(models.Model):
album = models.ForeignKey(Album, on_delete=models.CASCADE)
file_type = models.CharField(choices=TYPE_CHOICES, max_length=1)
caption = models.CharField(max_length=100)
class Meta:
ordering = ('upload_date', 'caption')
def get_absolute_url(self):
return reverse('picture:item-detail', kwargs={ 'id': self.album_id , 'pk': self.pk})
def __str__(self):
return self.caption
views.py
class ItemCreate(CreateView):
model = Item
fields = ['album', 'file_type', 'caption']
def get_initial(self):
album = get_object_or_404(Album, pk=self.kwargs.get('album.pk'))
return {
'album': album,
'file_type': 't',
}
urls.py
urlpatterns = [
# /picture/<album_id>/
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
# /picture/<album_id>/<pic_id>
url(r'^(?P<id>[0-9]+)/(?P<pk>[0-9]+)/$', views.ItemDetailView.as_view(), name='item-detail'),
# /picture/<album_id>/pic/add
url(r'^(?P<id>[0-9]+)/pic/add/$', views.ItemCreate.as_view(), name='item-add'),
]
If you want to get the object(album) where album.pk == id ( id an URL parameter of 'item-add' ) then try this,
class ItemCreate(CreateView):
model = Item
fields = ['album', 'file_type', 'caption']
def get_initial(self):
album = get_object_or_404(Album, pk=self.kwargs['id'])
return {
'album': album,
'file_type': 't',
}

Django ListView filter objects

I have a simple structure Shop_list --> Product_list --> Product_detail
I want to filter Product class object by slug field, but I see zero products.
I think that the problem in get_queryset()
views.py
class HomePageView(ListView):
model = Shop
template_name = 'blog/shop_list.html'
page_kwarg = 'shop'
context_object_name = 'shops'
class ProductListView(ListView):
model = Product
template_name = 'blog/product_list.html'
page_kwarg = 'product'
context_object_name = 'products'
def get_queryset(self):
pattern = str(self.request)
pattern = pattern[1:]
slug = self.model.shop
return Product.objects.filter(shop__slug=pattern)
def produt_detail(request, **kwargs):
print(request)
product = get_object_or_404(Product, pk=kwargs["pk"])
return render(request, 'blog/product_detail.html', {'product': product})
models.py
class Shop(models.Model):
title = models.CharField(max_length=200)
image = models.ImageField(blank=True)
slug = models.SlugField(null=False, default="Shop")
def get_absolute_url(self):
return reverse('product_list', kwargs={'slug': self.slug})
class Product(models.Model):
shop = models.ForeignKey(Shop, on_delete=models.CASCADE, related_name="shop")
title = models.CharField(max_length=200)
price = models.CharField(max_length=200)
period_start = models.DateTimeField(blank=True, null=True)
period_end = models.DateTimeField(blank=True, null=True)
def get_absolute_url(self):
return reverse('product_detail', kwargs={'slug': self.shop.slug, 'pk': self.pk})
urls.py
urlpatterns = [
path('', HomePageView.as_view(), name='shop_list'),
path('<slug:slug>', ProductListView.as_view(), name='product_list'),
path('<slug:slug>/<int:pk>/', views.produt_detail, name='product_detail'),
]
product_list.html
{% for product in products %}
<a href="{% url 'product_detail' product.shop.slug product.shop.pk %}">
...
You filter with:
class ProductListView(ListView):
model = Product
template_name = 'blog/product_list.html'
page_kwarg = 'product'
context_object_name = 'products'
def get_queryset(self):
return Product.objects.filter(shop__slug=self.kwargs['slug'])

IntegrityError at /add-to-cart/test2/ NOT NULL constraint failed: core_order.items_id

The problem might be in views.py file in add_to_cart() method. this method is using 3 classes from models.py
Here is my views.py file
from django.shortcuts import render
from .models import Item, Order, OrderItem
from django.views.generic import ListView, DetailView
from django.shortcuts import reverse, get_object_or_404, redirect
from django.utils import timezone
class HomeView(ListView):
model = Item
template_name = 'home-page.html'
class ItemView(DetailView):
model = Item
template_name = 'product.html'
def checkout(request):
context = {
'items': Item.objects.all()
}
return render(request, 'checkout-page.html', context)
def add_to_cart(request, slug):
item = get_object_or_404(Item, slug=slug)
order_item = OrderItem.objects.create(item=item)
order_qs = Order.objects.filter(user=request.user, ordered=False)
if order_qs.exists():
order = order_qs[0]
if order.items.filter(item__slug=item.slug).exists():
order_item.quantity += 1
order_item.save()
else:
ordered_date = timezone.now()
order = Order.objects.create(
user=request.user, ordered_date=ordered_date)
order.items.add(order_item)
return redirect("core:product",
slug=slug)
my models.py file. the Order class id is creating the problem.
Exception Value: NOT NULL constraint failed: core_order.items_id
Exception Type: IntegrityError
from django.conf import settings
from django.db import models
from django.shortcuts import reverse, get_object_or_404, redirect
Categoty_choice = (
('s', 'Shirt'),
('sw', 'Sport Wear'),
('o', 'Outwear')
)
Label_choice = (
('p', 'primary'),
('s', 'secondary'),
('d', 'danger')
)
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
discount_price = models.FloatField(blank=True, null=True)
category = models.CharField(choices=Categoty_choice, max_length=2)
label = models.CharField(choices=Label_choice, max_length=1)
slug = models.SlugField()
description = models.TextField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("core:product", kwargs={"slug": self.slug})
def get_add_to_cart_url(self):
return reverse("core:add_to_cart", kwargs={"slug": self.slug})
class OrderItem(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
def __str__(self):
return self.item
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
items = models.ForeignKey(OrderItem, on_delete=models.CASCADE)
start_date = models.DateTimeField(auto_now_add=True)
ordered_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
def __str__(self):
return self.user.username
urls.py file. some patterns ar CBV and some patterns are normal
from django.urls import path
from . import views
app_name = 'core'
urlpatterns = [
path('', views.HomeView.as_view(), name='home'),
path('product/<slug>/', views.ItemView.as_view(), name='product'),
path('add-to-cart/<slug>/', views.add_to_cart, name='add_to_cart'),
path('checkout/', views.checkout, name='checkout'),
]
You should add more attribute like null = True, blank = True
class OrderItem(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE, null=True, blank=True)
quantity = models.IntegerField(default=1)
def __str__(self):
return self.item
I was migrating without setting the new field blank = True, null = True. So the existing objects throw out errors because they didn't have any value in the newly added field. So I opened up the manage.py shell and fetched all the objects from that class and individually deleted all objects. Then adding blank = True, null = True to the newly added field, I migrated again. Then added objects again.

Category based list View in django

I have two model 1 is category, 2nd is details and I want make a view where i can click on a category and the link should take me to the list only for the current category what i clicked.
my models are given:
class FoodCategory(models.Model):
categoryname = models.CharField(max_length=100)
categorydetails = models.CharField(max_length=1000)
categoryimage = models.ImageField(default='cat_def.jpg',
upload_to='catimg')
class Meta:
verbose_name = 'Food Category'
def __str__(self):
return self.categoryname
class FoodDetails(models.Model):
fromcategory = models.ForeignKey(FoodCategory,
on_delete=models.CASCADE)
foodname = models.CharField(max_length=100)
fooddetails = models.CharField(max_length=1000)
foodimage = models.ImageField(default='food_def.jpg',
upload_to='fodimg')
armodel = models.CharField(default='andy.sfb', max_length=50)
additiondate = models.DateTimeField(default=timezone.now)
addedby = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
verbose_name = 'Food Detail'
def __str__(self):
return self.fromcategory.categoryname + \
' - ' + self.foodname + \
' - ' + 'added by' + \
' - ' + self.addedby.username
def get_absolute_url(self):
return reverse('food-details', kwargs={'pk': self.pk})
views.py file:
from django.shortcuts import render
from food.models import FoodCategory, FoodDetails
from django.views.generic import ListView, DetailView
class FoodCategoryView(ListView):
model = FoodCategory
template_name = 'food/food-category.html'
context_object_name = 'food'
class FoodListView(ListView):
model = FoodDetails
template_name = 'food/food-list.html'
context_object_name = 'food'
ordering = ['-additiondate']
class FoodDetailsView(DetailView):
model = FoodDetails
template_name = 'food/FoodDetails_detail.html'
and my urls.py file also:
from django.urls import path, include
from . import views
from .views import FoodCategoryView, FoodListView, FoodDetailsView
# api url handler
urlpatterns = [
path('category/', FoodCategoryView.as_view(), name='food-
category'),
path('foodlist/', FoodListView.as_view(), name='food-list'),
path('foodlist/<int:pk>/', FoodDetailsView.as_view(),
name='food-details')
]
here is my all files and i just want know a specific way to get the current category based food details.
You can do this by defining get_queryset on a listview.
class FoodDetailsByCategory(ListView):
def get_queryset(self):
return FoodDetails.objects.filter(fromcategory_id=self.kwargs['category_id'])
with a simple URL:
path('category/<int:category_id>', FoodDetailsByCategory.as_view(), name='food_details_by_category')

Categories