Stack Exchange
Django CBV - change FBV to CBV
Writing my first "real" django project I realized that my views are really huge. I try to convert it into CBV (as additional django training). Here are my fbv views:
def index(request):
    context = {}
    categories = Category.objects.select_related()
    subcategories = SubCategory.objects.all()
    context['categories'] = categories
    context['subcategories'] = subcategories
    return render(request, 'mainapp/index.html', context)


def category(request, category_name_slug):
    context = {}
    try:
        category = Category.objects.get(slug=category_name_slug)
        subcategory = SubCategory.objects.filter(category=category)
        context['subcategories'] = subcategory
        context['category'] = category
    except Category.DoesNotExist:
        raise Http404("Category doesn't exist")
    return render(request, 'mainapp/category.html', context)


def subcategory(request, category_name_slug, subcategory_name_slug):

    context = {}
    form = SiteAddForm(initial={'url': 'http://'})
    context['form'] = form
    try:
        category = Category.objects.get(slug=category_name_slug)
        subcategory = SubCategory.objects.filter(category=category
                                                 ).get(slug=subcategory_name_slug)
        sites = Site.objects.filter(subcategory=subcategory, is_active=True)
        context['subcategory'] = subcategory
        context['category'] = category
        context['sites'] = sites
    except (SubCategory.DoesNotExist, Category.DoesNotExist):
        raise Http404("Nie ma takiej strony")
    if request.method == 'POST':
        form = SiteAddForm(request.POST)
        if form.is_valid():
            siteurl = form.cleaned_data['url']
            context['siteurl'] = siteurl
            try:
                page = AddNewSite(siteurl)
            except:
                print('ERRROR')
                context['Error'] = "URL is not responding"
                return render(request, 'mainapp/subcategory.html', context)
            title = page.title()
            description = page.description()
            keywords = page.keywords()
            if page.check_url_in_database():
                context['Error'] = "Site already in database"
                return render(request, 'mainapp/subcategory.html', context)
            else:
                form_extended = SiteAddFormFull(initial={'url': siteurl, 'name':
                                                     title, 'description':
                                                     description, 'keywords':
                                                     keywords})
            context['form_extended'] = form_extended
            if request.method == 'POST':
                form_extended = SiteAddFormFull(request.POST)
                if form_extended.is_valid():
                    keywords = form_extended.cleaned_data['keywords']
                    name = form_extended.cleaned_data['name']
                    description = form_extended.cleaned_data['description']
                    page.add_site(category, subcategory, keywords,
                                  description, name, siteurl)
                    context['added_site'] = 'Thank you - site was added'
                    messages.add_message(request, messages.SUCCESS, 'Dodano!!')

return render(request, 'mainapp/subcategory.html', context)

How Can I simpy write my base view (index) using CBV. It should look that way:
Category:
    Sub1
    Sub2
Category2:
    Sub2a
    Sub2b
Should I learn CBV or stay using FBV (it works)? Below are my Category, Subcategory models:
class Category(models.Model):
    name = models.CharField(max_length=30, unique=True,
                        verbose_name='Category name')
    slug = models.SlugField()
    image = models.ImageField(upload_to='category_images',
                          verbose_name="Category image",
                          blank=True)
    description = models.TextField(default='Description',
                               verbose_name="Category description")

    class Meta:
        verbose_name_plural = "Categories"

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Category, self).save(*args, **kwargs)

    def image_thumb(self):
        if self.image:
            return '<img src="/media/%s" width="40" height="40" />' % (self.image)
        else:
            return('')
    image_thumb.short_description = 'Thumb'
    image_thumb.allow_tags = True

    def __str__(self):
        return self.name


class SubCategory(models.Model):
    category = models.ForeignKey(
        'Category',
        related_name='subcategory',
        on_delete=models.CASCADE,
        blank=True,
        null=True,
)
    name = models.CharField(max_length=30)
    slug = models.SlugField()

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(SubCategory, self).save(*args, **kwargs)

    class Meta:
        verbose_name_plural = "Subcategories"

    def __str__(self):
        return self.name


this is more like asking us to do it. :) anyway it's pointless to convert FBV to CBV just for the sake of doing so

No, it is not. I would like to get any advice, clues, whatever... Maybe in your opinion my fbv is good enough... I don't know, I am only asking.

"Maybe in your opinion ..." already one flag for primarily opinon based

CBV are no magic bullet. If your FBV is a mess, your CBV is gonna be a mess too. If you want to improve your code, start by improving your FBV. When you think your FBV is in a good shape, you can try refactoring it to a CBV if that's what you want.

Converting FBV to CBV is good practice and should help learn the details of the CBV approach.

I'm an advocate of CBV, it can make life a lot easier when trying to reuse code. There are also a ton of pre-defined generic views that only need a small tweaks for most instances. For your example index, you can use a TemplateView:
class IndexView(TemplateView):
    template_name = "mainapp/index.html"

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['categories'] = Category.objects.select_related()
        context['subcategories'] = SubCategory.objects.all()
        return context

