Home > Software design >  Creating category section with django
Creating category section with django

Time:11-07

I'm trying to add a category section to my blog post form using django, the category field is created and I haven't got any error but the dropdown is not created.

models.py

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse


class Category(models.Model):
    name = models.CharField(max_length=200)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('posts')


class Post(models.Model):
    STATUS = [
        (0, 'Drafted'),
        (1, 'Published'),
    ]
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    published_on = models.DateTimeField(auto_now=True)
    content = models.TextField()
    status = models.IntegerField(choices=STATUS, default=0)
    category = models.CharField(max_length=200, default='uncategorized')

    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('my_blog:posts')

forms.py

from django import forms
from .models import Post


class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('title', 'author', 'category', 'content')

        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'author': forms.Select(attrs={'class': 'form-control'}),
            'category': forms.Select(attrs={'class': 'form-control'}),
            'content': forms.Textarea(attrs={'class': 'form-control'}),
        }

admin.py

from django.contrib import admin
from .models import Post, Category, Comment


admin.site.register(Post)
admin.site.register(Category)

This method was based on a tutorial and I'm wondering if this is the right way to create category fields. Any help, please?

CodePudding user response:

You should use Category model as ForeignKey in Post model:

class Post(models.Model):
    ...
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True)
    ...

If you have uncategorized posts, you can set them to null. Otherwise, you should use models.CASCADE or models.PROTECT instead of models.SET_NULL at on_delete.

class Post(models.Model):
   ...
   category = models.ForeignKey(Category, on_delete=models.CASCADE)
   ...

After making changes to your model, you should not forget the following commands:

python manage.py makemigrations

python manage.py migrate

CodePudding user response:

you should give a unique=True to your Category name and in your Post model for category use a ForeignKey instead of CharField. By default a ForeignKey will be a select field so you shouldn't need to do much else.

Like this :

class Category(models.Model):
    name = models.CharField(max_length=200, unique=True)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('posts')


class Post(models.Model):
    STATUS = [
        (0, 'Drafted'),
        (1, 'Published'),
    ]
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)
    published_on = models.DateTimeField(auto_now=True)
    content = models.TextField()
    status = models.IntegerField(choices=STATUS, default=0)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='posts')

    class Meta:
        ordering = ['-created_on']

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('my_blog:posts')
  • Related