Как работать с MultipleCheckBox в Django?
добрый день, я новичок в django и пытаюсь сделать приложение, которое регистрирует посещаемость предпринимателей (я сейчас работаю с этим). Есть некоторые услуги, которые я хотел бы выбрать, иногда один и тот же человек требует более одной услуги за прием. Однако, часть приложения использует модели, а часть - формы, я хотел бы держать их отдельно, чтобы сохранить код организованным, но я понятия не имею, как это сделать, я даже создал отдельный класс только для кортежа, который хранит значения, но ни один из них мне не удалось реализовать, может ли кто-нибудь помочь мне? Вот коды:
models.py
from django.db import models
from django_cpf_cnpj.fields import CPFField, CNPJField
class CadastroEmpreendedor(models.Model):
ABERTURA = 'ABERTURA MEI'
ALTERACAO = 'ALTERAÇÃO CADASTRAL'
INFO = 'INFORMAÇÕES'
DAS = 'EMISSÃO DAS'
PARC = 'PARCELAMENTO'
EMISSAO_PARC = 'EMISSÃO DE PARCELA'
CODIGO = 'CÓDIGO DE ACESSO'
REGULARIZE = 'REGULARIZE'
BAIXA = 'BAIXA MEI'
CANCELADO = 'REGISTRO BAIXADO'
descricao_atendimento = (
(ABERTURA, 'FORMALIZAÇÃO'),
(ALTERACAO, 'ALTERAÇÃO CADASTRAL'),
(INFO, 'INFORMAÇÕES'),
(DAS, 'EMISSÃO DAS'),
(PARC, 'PARCELAMENTO'),
(EMISSAO_PARC, 'EMISSÃO DE PARCELA'),
(CODIGO, 'CÓDIGO DE ACESSO'),
(REGULARIZE, 'REGULARIZE'),
(BAIXA, 'BAIXA MEI'),
(CANCELADO, 'REGISTRO BAIXADO'),
)
cnpj = CNPJField('CNPJ')
cpf = CPFField('CPF')
nome = models.CharField('Nome', max_length=120)
nascimento = models.DateField()
email = models.EmailField('Email', max_length=100)
telefone_principal = models.CharField(max_length=11)
telefone_alternativo = models.CharField(max_length=11, blank=True)
descricao_atendimento
def __str__(self) -> str:
return self.nome
class DescricaoAtendimento(models.Model):
descricao = models.ForeignKey(CadastroEmpreendedor, on_delete=models.CASCADE)
forms.py
from django import forms
from .models import DescricaoAtendimento
class EmpreendedorForm(forms.ModelForm):
class Meta:
model = DescricaoAtendimento
fields = ['descricao']
widgets = {'descricao': forms.CheckboxSelectMultiple(),}
views.py
from django.shortcuts import render
from django.contrib import messages
from .forms import EmpreendedorForm
def cadastro_empreendedor(request):
if str(request.method) == 'POST':
form = EmpreendedorForm(request.POST, request.FILES)
if form.is_valid():
form.save()
messages.success(request, 'Produto salvo com sucesso!')
form = EmpreendedorForm()
else:
messages.success(request, 'Erro ao salvar produto!')
else:
form = EmpreendedorForm()
context = {
'form': form
}
return render(request, 'empreendedor.html', context)
Если у вас есть какие-либо советы, я буду очень признателен, я начал с django почти месяц назад, так что предстоит долгий путь.
P.s: Я интегрировался с PostgreSQL и в административной части django я могу сохранить все поля в БД, но я не могу реализовать эту часть чекбокса.
В этот момент я получаю ошибку:
It is impossible to add a non-nullable field 'descricao' to descricaoatendimento without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit and manually define a default value in models.py.
В шаблоне я собираюсь работать с bootstrap4 для создания форм. Но я хотел бы решить этот вопрос до того, как. Я все еще учу английский, так что извините за некоторые ошибки.
Похоже, что у вас много предпринимателей, каждый из которых может выбрать много услуг. Это отношение ManyToMany, и вы можете создать его в Django, имея одну модель для каждого и создавая связь между ними следующим образом
class CadastroEmpreendedor(models.Model):
...
descricao_atendimento = models.ManyToManyField(DescricaoAtendimento)
class DescricaoAtendimento(models.Model):
nome = models.CharField('Nome', max_length=120, default="unnamed service")
В этом случае каждый объект/строка в DescricaoAtendimento является услугой. Каждый предприниматель может иметь много услуг, связанных с ним.
Таким образом, вам не нужно создавать типовую форму для DescricaoAtendimento, чтобы выбрать услуги для предпринимателя. Поскольку он связан с ними отношением manytomany, вы можете иметь модельную форму CadastroEmpreendedor только с полем escricao_atendimento, и различные услуги станут доступны как опции.
Django решает эту проблему путем создания "сквозной таблицы", которая, по сути, представляет собой таблицу с двумя полями внешних ключей, одно из которых указывает на предпринимателя, а другое - на сервис. Вы также можете создать эту таблицу самостоятельно как сквозную таблицу - что полезно, если вы хотите расширить данные об отношениях - например, дату начала и окончания использования услуги предпринимателем.
Ошибка, которую вы получаете при миграции, сама по себе не является ошибкой. Похоже, что вы создали ряд объектов DescricaoAtendimento, а затем добавили поле descricao. Когда вы затем пытаетесь выполнить миграцию, django требует, чтобы вы предоставили значение по умолчанию для уже существующих строк или позволили полю быть пустым (через blank=True в модели). Вы можете присвоить фиктивное значение, а затем вернуться и изменить его в /admin позже, или, если у вас не так много данных, пересоздать базу данных и выполнить повторную миграцию. Выше я использовал значение по умолчанию, чтобы избежать этой ситуации.