Linkify Foreign Keys with Django Tables2 and Slugs - python

I am trying to build summary tables with clickable links that drill down to lower levels. The hierarchy in descending order is Division -> Region -> Branch -> Profit Center where each profit center can have multiple "receivables." I want the division summary view to show all of the regions (e.g. California, Central Texas, Ohio, etc) and a sum of the 'total_amount' for the regions.
I want to be to click a region and it drills down to the branches where I can see a summary for each branch. So on and so forth
I've spent far longer than I would like to admit on this and the lines commented out on tables.py is just a fraction of what I have tried.
What am I missing?
class Division(models.Model):
name = models.CharField(max_length=128, unique=True)
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('division-detail', args=[str(self.slug)])
class Region(models.Model):
name = models.CharField(max_length=128, unique=True)
division = models.ForeignKey('Division', to_field='name', on_delete=models.CASCADE)
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('region-summary', args=[str(self.slug)])
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)
class Branch(models.Model):
name = models.CharField(max_length=128)
number = models.CharField(max_length=4, unique=True)
region = models.ForeignKey('Region', to_field='name', on_delete=models.CASCADE)
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return self.number
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.number)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('branch-detail', args=[str(self.slug)])
class Profit_Center(models.Model):
branch = models.ForeignKey('Branch', on_delete=models.CASCADE)
number = models.CharField(max_length=32, unique=True, editable=False, null=True, blank=True)
slug = models.SlugField(unique=True, null=True)
class Receivable(models.Model):
document = models.IntegerField(primary_key=True, blank=False)
payer = models.ForeignKey('Payer', on_delete=models.PROTECT)
profit_center = models.ForeignKey(Profit_Center, to_field = 'number', on_delete=models.PROTECT, null=True)
total_amount = models.DecimalField(decimal_places=2, max_digits=20, null=True, blank=True)
slug = models.SlugField(unique=True, null=True, editable=False)
tables.py
#summary by selected division, showing summary by region
class ReceivableDivisionSummaryHTMxTable(tables.Table):
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'slug': 'central-texas'})) #always goes to central texas
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'region': tables.A('region'), 'slug': tables.A('region.slug')})) #fails on accessor key
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'slug': tables.A('profit_center__branch__region.slug')}))
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'slug': tables.A('name')})) #fails on accessor key
#profit_center__branch__region = tables.LinkColumn('region-summary', args=[A('profit_center__branch__region.slug')])
#profit_center__branch__region = tables.Column(linkify=True)
#profit_center__branch__region = tables.LinkColumn('region-summary', kwargs={'slug': 'record.slug'}) #half-ass works, returns regionsummary/region_slug insteald of the real slug
#profit_center__branch__region = tables.LinkColumn('region-summary', args=[A('pk')])
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'pk': tables.A('region__pk')})) #half-ass works, returns regionsummary/region_slug insteald of the real slug
#profit_center__branch__region = tables.LinkColumn('region-summary', args=[A('slug')])
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'slug': tables.A('region.slug')}))
#species =tables.TemplateColumn('{{value}}')
profit_center__branch__region = tables.TemplateColumn('{{value}}') #sooooo fucking close, returns the division- (e.g. Ford) rather region (e.g. Ohio), though it displays Ohio correctly as the value
class Meta:
model = Receivable
template_name = 'tables/bootstrap_htmx.html'
fields = ('profit_center__branch__region', 'sum_col')
views.py
def ReceivableDivisionSummaryHTMxTableView(request, slug):
#post = get_object_or_404(Receivable, slug=slug)
queryset = Receivable.objects.values('profit_center__branch__region').annotate(sum_col=Sum('total_amount'))
table= ReceivableDivisionSummaryHTMxTable(queryset)
context = {'table': table, 'slug': slug}
if request.htmx:
template_name = "app/receivable_table_partial.html"
else:
template_name = 'app/receivable_summary_htmx.html'
template_name
return render(request, template_name, context)
def ReceivableRegionSummaryHTMxTableView(request, slug):
queryset = Receivable.objects.values('profit_center').annotate(sum_col=Sum('total_amount'))
table= ReceivableRegionSummaryHTMxTable(queryset)
context = {'table': table, 'slug':slug}
if request.htmx:
template_name = "app/receivable_table_partial.html"
else:
template_name = 'app/receivable_summary_htmx.html'
template_name
return render(request, template_name, context)
Update: I've reduced it to the absolute bare minimum and I am still running into the error: for linkify=True, '100100' must have a method get_absolute_url
100100 is a profit center
models.py
class Profit_Center(models.Model):
branch = models.ForeignKey('Branch', on_delete=models.CASCADE)
number = models.CharField(max_length=32, unique=True, editable=False, null=True, blank=True)
profit_center_slug = models.SlugField(unique=True, null=True)
def get_absolute_url(self):
return reverse('branch-detail', args=[str(self.profit_center_slug)])
class Receivable(models.Model):
document = models.IntegerField(primary_key=True, blank=False)
profit_center = models.ForeignKey(Profit_Center, to_field = 'number', on_delete=models.PROTECT, null=True)
total_amount = models.DecimalField(decimal_places=2, max_digits=20, null=True, blank=True)
receivable_slug = models.SlugField(unique=True, null=True, editable=False)
tables.py
class AllProfitCenterSummaryHTMxTable(tables.Table):
profit_center = tables.Column(linkify=True)
class Meta:
model = Receivable
template_name = 'tables/bootstrap_htmx.html'
fields = ('profit_center', 'sum_col', )
views.py
def AllProfitCenterSummaryHTMxTableView(request):
queryset = Receivable.objects.values('profit_center').annotate(sum_col=Sum('total_amount'))
table= AllProfitCenterSummaryHTMxTable(queryset)
if request.htmx:
template_name = "app/receivable_table_partial.html"
else:
template_name = 'app/receivable_summary_htmx.html'
template_name
return render(request, template_name, {'table':table})
urls.py
path('htmx/allprofitcentersummary/', views.AllProfitCenterSummaryHTMxTableView, name='all-profit-center-summary'),
Update 2: getting closer. I've got it half working with the below code:
class ReceivableDivisionSummaryHTMxTable(tables.Table):
class Meta:
model = Receivable
template_name = 'tables/bootstrap_htmx.html'
fields = ('profit_center__branch__region', 'sum_col',)
def render_profit_center__branch__region(self, value):
return format_html('{}', value, value)
However, it is taking the text value of the field (e.g. Central Texas). However, I need it to be slugified (e.g. central-texas). I tried to do it with the following, but it isn't taking.
def render_profit_center__branch__region(self, value):
value_slug = value
slugify(value_slug)
return format_html('{}', value_slug, value)
Can I pass a slug into the render?
Update 3: I've got the slugification to work with the following:
def render_profit_center__branch__region(self, value):
return format_html('{}', slugify(value), value)
However, I still need to pass a slug into the render. I want my links to formatted as divisionsummay/NAMEOFDIVSION/regionsummary/NAMEOFREGION
I need to pass a slug back to the render similar to the following:
def render_profit_center__branch__region(self, value, division_slug):
return format_html('{}', division_slug, slugify(value), value)
Obviously, that isn't working. Not sure how to pass the division_slug.

Update 4: went a different route. Instead of having divisionsummay/NAMEOFDIVSION/regionsummary/NAMEOFREGION, I am simply going to have separate urls (e.g. app/htmx/divisionsummary/NAMEOFDIVISON, app/htmx/regionsummary/NAMEOFREGION, etc).
Achieved via the following:
def render_profit_center__branch__region(self, value):
return format_html('{}', reverse_lazy('region-summary', args=[slugify(value)]), value)

Related

Get backward relationships items for model in Django

I have a pet project with reviews about spare parts for cars.
Here is models.py:
class CarBrand(models.Model):
brand = models.CharField(max_length=40, choices=(), unique=True, verbose_name="Марка")
def __str__(self):
return self.brand
def get_absolute_url(self):
return reverse_lazy('car_models_all', kwargs={'car_id': self.pk})
class CarModel(models.Model):
model_name = models.CharField(max_length=60, db_index=True, verbose_name="Модель")
brand_id = models.SmallIntegerField(verbose_name="ID марки")
def __str__(self):
return self.model_name
def get_absolute_url(self):
return reverse_lazy('model_info', kwargs={'model_id': self.pk})
class SparePartCategory(models.Model):
name = models.CharField(max_length=255, db_index=True, verbose_name='Название')
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse_lazy('spare_parts_category', kwargs={'category_id': self.pk})
class SparePart(models.Model):
name = models.CharField(max_length=255, db_index=True, verbose_name='Название')
brand = models.CharField(max_length=255, db_index=True, verbose_name="Производитель")
number = models.CharField(max_length=30, db_index=True, verbose_name="Номер (артикул)")
category = models.ForeignKey(SparePartCategory, on_delete=models.PROTECT, verbose_name="Категория")
def __str__(self):
return ' '.join([self.name, self.brand, self.number])
def get_absolute_url(self):
return reverse_lazy('get_spare_part', kwargs={'spare_part_id': self.pk})
class Review(models.Model):
RATING_VALUES = [
('1', 'Ужасно'), ('2', 'Плохо'), ('3', 'Сносно'), ('4', 'Хорошо'), ('5', 'Отлично'),
]
spare_part = models.ForeignKey(SparePart, on_delete=models.PROTECT, verbose_name="Запчасть")
mileage = models.SmallIntegerField(verbose_name="Пробег, тыс.км")
car_brand = models.ForeignKey(CarBrand, on_delete=models.PROTECT, verbose_name="Марка авто")
car_model = models.ForeignKey(CarModel, on_delete=models.PROTECT, verbose_name="Модель авто")
owner = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="Владелец")
rating = models.CharField(max_length=1, choices=RATING_VALUES, verbose_name="Рейтинг", default=3)
review = models.TextField(max_length=1000, blank=True, verbose_name="Отзыв")
def __str__(self):
return ' '.join([self.spare_part.name, self.spare_part.brand, self.spare_part.number])
In views.py I get one SparePart
def get_spare_part(request, spare_part_id):
spare_part = get_object_or_404(SparePart, pk=spare_part_id)
installed_on_cars = # here I need to get all CarModel for current SparePart with Review exists
context = {
'spare_part': spare_part,
'installed_on_cars': installed_on_cars,
}
return render(request, 'mileage/spare_part.html', context)
I need to get all CarBrand and CarModel for current SparePart with Review exists, and get hyperlinks for template for them. How do I can to implement this?
I think I need to make it with backward relationships, but can not understand how.
Use the _set manager object (documentation here).
for review in spare_part.review_set.all():
print(f'brand: {review.care_brand}')
print(f'model: {review.car_model}')
If you define a related_name (e.g. 'reviews) for spare_parts in Review, you can use that name for backward query instead of _set (e.g. spare_part.reviews.all()).

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.

Django Formset: Add lines from an existing product catalog?

I have got a form with a formset that allows me to add some lines to it. I can add some simple lines. But I also wanted to add some products from a product catalog.
So the process will be as following:
User create a new purchase order (Working)
User add lines as explained below (Working)
User a button add lines from existing product catalog. The user will then browse or filter the product, he wants to order and add it to the purchase order.
I know what I am trying to do is wrong as I guess we can not have two def get_context_data(self, **kwargs): in the function. What would be the idea to be able to add products from the catalog in my formset?
Many Thanks,
Product list
models.py
class BaseProduct(models.Model):
"""
Abstract base product model class providing the base fields and methods
"""
supplier = models.CharField(max_length=300, blank=True, null=True)
manufacturer = models.CharField(max_length=300, blank=True, null=True)
product_range = models.CharField(max_length=300, blank=True, null=True)
part_number = models.CharField(_('Item Code'), max_length=255, blank=True, null=True)
description = models.CharField(_('description'), max_length=255, blank=True, null=True)
Orders
views.py
class OrderCreate(CreateView):
model = Order
template_name = 'accounting/orders/create_order.html'
form_class = OrderForm
success_url = None
def get_context_data(self, **kwargs):
data = super(OrderCreate, self).get_context_data(**kwargs)
if self.request.POST:
data['lines'] = OrderLineFormSet(self.request.POST)
else:
data['lines'] = OrderLineFormSet()
return data
def get_context_data(self, **kwargs):
data = super(OrderCreate, self).get_context_data(**kwargs)
if self.request.POST:
data['productlines'] = OrderProductLineFormSet(self.request.POST)
else:
data['productlines'] = OrderProductLineFormSet()
return data
def form_valid(self, form):
context = self.get_context_data()
lines = context['lines']
with transaction.atomic():
form.instance.created_by = self.request.user
self.object = form.save()
if lines.is_valid():
lines.instance = self.object
lines.save()
return super(OrderCreate, self).form_valid(form)
def get_success_url(self):
return reverse('accounting:detail_order', kwargs={'order_id': self.object.pk})
#method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(OrderCreate, self).dispatch(*args, **kwargs)
models.py
class OrderLine(models.Model):
order = models.ForeignKey('Order', on_delete=models.CASCADE, related_name="has_lines", blank=True, null=True)
order_item = models.CharField(max_length=100, verbose_name="Line", blank=True, null=True)
tax_rate = models.ForeignKey('TaxRate', on_delete=models.CASCADE, blank=True, null=True)
total = models.CharField(max_length=250, blank=True, null=True)
description = models.CharField(max_length=100, blank=True, null=True)
unit_price_excl_tax = models.DecimalField(max_digits=8,decimal_places=2, blank=True, null=True)
quantity = models.DecimalField(max_digits=8,decimal_places=2,default=1, blank=True, null=True)
def total(self):
total = Decimal(str(self.unit_price * self.quantity))
return total.quantize(Decimal('0.01'))
def __unicode__(self):
return self.description
class Meta:
pass
class OrderProductLine(models.Model):
order = models.ForeignKey('Order', on_delete=models.CASCADE, related_name="has_lines", blank=True, null=True)
baseproduct = models.ForeignKey('BaseProduct', on_delete=models.CASCADE, related_name="has_product_lines", blank=True, null=True)
order_item = models.CharField(max_length=100, verbose_name="Product_Line", blank=True, null=True)
tax_rate = models.ForeignKey('TaxRate', on_delete=models.CASCADE, blank=True, null=True)
total = models.CharField(max_length=250, blank=True, null=True)
description = models.CharField(max_length=100, blank=True, null=True)
unit_price_excl_tax = models.DecimalField(max_digits=8,decimal_places=2, blank=True, null=True)
quantity = models.DecimalField(max_digits=8,decimal_places=2,default=1, blank=True, null=True)
def total(self):
total = Decimal(str(self.unit_price * self.quantity))
return total.quantize(Decimal('0.01'))
def __unicode__(self):
return self.description
class Meta:
pass
forms.py
class OrderLineForm(forms.ModelForm):
class Meta:
model = OrderLine
exclude = ()
OrderLineFormSet = inlineformset_factory(
Order, OrderLine, form=OrderLineForm,
fields=['order_item', 'description','quantity','unit_price_excl_tax','tax_rate'], extra=1, can_delete=True
)
class OrderProductLineForm(forms.ModelForm):
class Meta:
model = OrderProductLine
exclude = ()
OrderProductLineFormSet = inlineformset_factory(
BaseProduct, OrderProductLine, form=OrderProductLineForm,
fields=['supplier', 'part_number','quantity','unit_price_excl_tax','tax_rate'], extra=1, can_delete=True
)
To fix the issue with your view you can combine the two get_context_data methods, but I am not sure if this will fix all the issues you are having
def get_context_data(self, **kwargs):
data = super(OrderCreate, self).get_context_data(**kwargs)
if self.request.POST:
data['lines'] = OrderLineFormSet(self.request.POST)
data['productlines'] = OrderProductLineFormSet(self.request.POST)
else:
data['lines'] = OrderLineFormSet()
data['productlines'] = OrderProductLineFormSet()
return data
More generally, it looks like you are trying to edit two models at the same time utilizing the ModelForm class. The best way to do this is to have two model forms submit through the same form rather than utilizing formsets. There is a good example of this here taken from this SO post. You should be able to find more details on this implementation in the two links.

Doesn't save data django Foreignkey model

I've two model. I would like to save data from ForeignKey model. I'm created a modelform and save with my main foreignkey model. But I got this error ValueError at /c/customer/1/
Cannot assign "'1'": "BillingData.customer" must be a "CustomerData" instance.
I created Django model form and hocked up with view.
models.py file
class CustomerData(models.Model):
customer_name = models.CharField(max_length=100)
customer_no = models.CharField(max_length=100, default='', blank=True)
mobile_number = models.IntegerField()
alternative_phone = models.IntegerField(null=True, blank=True)
union_name = models.ForeignKey(UnionName, on_delete=models.SET_NULL, null=True)
word_name = models.ForeignKey(UnionWordName, on_delete=models.SET_NULL, null=True)
full_address = models.CharField(max_length=200, null=True, blank=True)
create_date = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return '%s, Mobile: %s' % (self.customer_name, self.mobile_number)
def get_absolute_url(self):
return reverse('customer_data', kwargs={'pk': self.pk})
class BillingData(models.Model):
bill_no = models.CharField(max_length=100, default='', blank=True)
customer = models.ForeignKey(CustomerData, on_delete=models.CASCADE)
sales_person = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)
customer_money = models.IntegerField()
create_date = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return '%s %s' % (self.customer.customer_name, self.create_date.date())
def get_absolute_url(self):
return reverse('customers.views.BillingPage', kwargs={'pk': self.pk})
forms.py file
class BillCreateForms(forms.ModelForm):
bill_no = forms.CharField(max_length=100)
customer = forms.ChoiceField(choices=[(x.id, x.customer_name) for x in CustomerData.objects.all()])
customer_money = forms.IntegerField()
def save(self, commit=True):
instance = super(BillCreateForms, self).save(commit=False)
customer_pk = self.cleaned_data['customer']
instance.customer = CustomerData.objects.get(pk=customer_pk)
instance.save(commit)
return instance
class Meta:
model = BillingData
fields = ('bill_no', 'customer', 'customer_money',)
views.py file
class CustomerDataView(FormMixin, generic.DetailView):
model = CustomerData
form_class = BillCreateForms
template_name = "customers/customerdata_detail.html"
print(form_class)
success_url = '/c/'
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
I expect data save with foreignkey relation data. But doesn't save here.
You can't fix this problem in the save method, because the error happens before it gets that far.
You should be using a ModelChoiceField, not a ChoiceField. Not only would this fix the problem, it would also let you remove your entire save method.
customer = forms.ModelChoiceField(queryset=CustomerData.objects.all())
Change this line
instance.customer = CustomerData.objects.get(pk=customer_pk)
to
instance.customer_id = CustomerData.objects.get(pk=customer_pk).pk
Model:
class Blog(models.Model):
# ...
pass
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)
Set object
b = Blog.objects.get(id=1)
e = Entry.objects.get(id=234)
b.entry_set.add(e)

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