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