Как работать с 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 позже, или, если у вас не так много данных, пересоздать базу данных и выполнить повторную миграцию. Выше я использовал значение по умолчанию, чтобы избежать этой ситуации.

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