Выберите правильный выбор. Этот выбор не является одним из доступных вариантов --Django forms

Я новичок в Django. Я пытаюсь сделать выпадающую форму выбора (категории) в django.
Форма хорошо отображается на веб-странице, но когда я пытаюсь отправить, я получаю ошибку Выберите правильный выбор. Этот выбор не является одним из доступных вариантов. Я сделал все возможное, чтобы решить эту проблему. Если у вас есть идеи, как решить эту проблему, пожалуйста, помогите.

image

model.py

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

# Create your models here.
class Category(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('detail', args=[str(self.id)])
        # return reverse('home')

class Post(models.Model):
    title = models.CharField(max_length=100)
    text = models.TextField()
    author = models.ForeignKey(User,  on_delete=models.CASCADE)
    edited = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)
    category = models.CharField(max_length=100, default='coding')

    def __str__(self):
        return f'{self.title} by {self.author} {self.pk}'

    def get_absolute_url(self):
        return reverse('detail', args=[str(self.id)])
        # return reverse('home')

form.py

from django import forms
from .models import Post, Category

choices = Category.objects.all().values_list('name','name')
choices_list = []
for item in choices:
    choices_list.append(item)

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('title', 'category', 'author','text')
    widgets={
            'title': forms.TextInput(attrs={'class':'form-control'}),
            'category': forms.Select(choices=choices_list, attrs={'class':'form-control'}),
            'author': forms.TextInput(attrs={'class':'form-control', 'id':'author'}),
            # 'author': forms.Select(attrs={'class':'form-control'}),
            'text': forms.Textarea(attrs={'class':'form-control','placeholder':choices_list}),
}

class EditForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('title', 'text')
        widgets={
            'title': forms.TextInput(attrs={'class':'form-control'}),
            'text': forms.Textarea(attrs={'class':'form-control','placeholder':"less than 500 words"}),
            # 'author': forms.Select(attrs={'class':'form-control'})
}

views.py

class createarticleview(CreateView):
    template_name='posts/addpost.html'
    model = Post
    form_class = PostForm
    #fields = '__all__'
    # fields = ('title','text') for certain fields
    def get_context_data(self, *args, **kwargs):
        cat_menu = Category.objects.all()
        context = super(createarticleview, self).get_context_data(*args, **kwargs)
        context['cat_menu'] = cat_menu
        return context  

addpost.html

{%extends 'index.html'%}
{%block content%}
{% if user.is_authenticated %}
    <div class="container">
        <h3>add post...!!!.{{user.username}}</h3>
        <br>
        <div class="mb-3">
        <form method="POST"> {% csrf_token%}
        {{form.as_p}}
        <button type="submit" class="btn btn-info"> post</button>           
        </form>
    </div>
    </div>

    <script>
        
        var name = "{{user.username}}";
    if(document.getElementById("author").value=name)
    document.getElementById('author').readOnly = true;
  

    </script>
{% else%}
        <h3>you are not logged in</h3>
{%endif%}
{%endblock content%}

Во-первых, всегда используйте PascalCase при определении имени class, например, вы можете дать CreateArticleView, а не createarticleview.

вы не дали choices при определении вашей модели, которая есть Post и дана models.CharField().

Обновите вашу Post модель с помощью choices атрибута.

Попробуйте это:

models.py


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

CATEOGRY_TYPES = (
    ('sp', 'sport'),
    ('te', 'technology'),
    ('bu', 'business')
)


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

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('detail', args=[str(self.id)])
        # return reverse('home')


class Post(models.Model):
    title = models.CharField(max_length=100)
    text = models.TextField()
    author = models.ForeignKey(User,  on_delete=models.CASCADE)
    edited = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)
    category = models.CharField(
        choices=CATEOGRY_TYPES, max_length=2, default='coding')

    def __str__(self):
        return f'{self.title} by {self.author} {self.pk}'

    def get_absolute_url(self):
        return reverse('detail', args=[str(self.id)])
        # return reverse('home')

views.py

from django.shortcuts import render
from .models import Post, Category
from .forms import PostForm
from django.views.generic.edit import CreateView


class CreateArticleView(CreateView):
    template_name = 'posts/addpost.html'
    model = Post
    form_class = PostForm
    success_url = '/success/'


def success(req):
    return render(req, 'posts/success.html')

Остальные вещи останутся прежними.

Вы можете сделать это без метода reverse, непосредственно создав поле ForeignKey в вашей Post модели.

Вы также можете сделать следующее:

models.py

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


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

    def __str__(self):
        return self.name


class Post(models.Model):
    title = models.CharField(max_length=100)
    text = models.TextField()
    author = models.ForeignKey(User,  on_delete=models.CASCADE)
    edited = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)
    category = models.ForeignKey(
        Category, on_delete=models.CASCADE, default='coding')

    def __str__(self):
        return f'{self.title} by {self.author} {self.pk}'

views.py

from django.shortcuts import render
from .models import Post, Category
from .forms import PostForm
from django.views.generic.edit import CreateView


class CreateArticleView(CreateView):
    template_name = 'posts/addpost.html'
    model = Post
    form_class = PostForm
    success_url = '/success/'


def success(req):
    return render(req, 'posts/success.html')

Ваш forms.py может остаться прежним.

Помните: choices при определении моделей будет отдаваться большее предпочтение, чем ForeignKey.

Вернуться на верх