How can I convert a QuerySet list to a list or a dataset for the choices field?

After doing some filters and operations, I write the data to the model.

I get the data after processing in the model. Then I unload the data when displaying the form.

There is a field in the form - which is like a choices field. But I'm not quite sure about the correct spelling for the form.

My problem is that I can display the data for the choices field only after some processing or as a result of receiving data from another model.

My task is to unload data from another model into the code. And then from the code send it to the choices field. How can I do something similar?

models.py

class Category_pk_for_form_maim (models.Model):
    categoty_name = models.CharField()
    def __str__(self):
        return self.categoty_name
    

class Category_pk_for_form_category (models.Model):
    name_object = models.IntegerField(verbose_name="Наименование объекта")
    category_name = models.CharField()

 
class CreateNewGPR (models.Model):
    name_object = models.IntegerField(verbose_name="Наименование объекта")
    name_category = models.CharField(verbose_name="Наименование категории/раздела/вида работ")
    name_working = models.CharField(verbose_name="Наименование работы")
    type_izm = models.CharField(choices=TYPE_IZMERENIYA, verbose_name="Единицы измерения")
    value_work = models.FloatField(verbose_name="Объём работ")
    lyudi_norma = models.IntegerField(verbose_name="Нормативные затраты персонала")
    technik_norma = models.IntegerField(verbose_name="Нормативные затраты техники")
    date_begin = models.DateField(verbose_name="Дата начала работ")
    date_end = models.DateField(verbose_name="Дата окончания работ")


class GPRWorkingName (models.Model):
    name_working = models.CharField(verbose_name="Наименование работы по ГПР")  
    def __str__(self):
        return self.name_working   

forms.py

class Form_GPR (forms.ModelForm):
    class Meta:
        model = CreateNewGPR
        fields = "name_category", "name_working", "type_izm", "value_work", "lyudi_norma", "technik_norma", "date_begin", "date_end"
        widgets = {
            "name_category": forms.RadioSelect(attrs={"type":"radio"}),
            "date_begin": forms.DateInput(attrs={"class":"form-control", "type":"date"}),
            "date_end": forms.DateInput(attrs={"class":"form-control", "type":"date"}),
            
        }

views.py

def book(request, pk):

    context = {}

    Category_pk_for_form_maim.objects.all().delete()

    filter_qs_category = Category_pk_for_form_category.objects.filter(name_object=pk)
    filter_qs_category = filter_qs_category.values("category_name")

    for item in filter_qs_category:
        entry = item
        new_entry = Category_pk_for_form_maim(categoty_name=entry)
        new_entry.save()

    form_category_1 = Category_pk_for_form_category_Form()
    form_2 = Form_GPR()

    choises_1 = Category_pk_for_form_maim.objects.all()
    choises_1 = choises_1.values_list("categoty_name", flat=True)

    choises_1 = choises_1.values()

    print(choises_1)


    form_2.fields["name_category"].choices = choises_1

    if request.method == 'POST':

        if request.POST.get("form_type") == "form1":
            form_category_1 = Category_pk_for_form_category_Form(request.POST) 
            if form_category_1.is_valid():
                model_instance = form_category_1.save(commit=False)
                name_object = pk
                category_name = model_instance.category_name
                new_entry = Category_pk_for_form_category(name_object=name_object, category_name=category_name)
                new_entry.save()
                return redirect("book-detail", pk)            
        elif request.POST.get("form_type") == "form2":
            form_2 = Form_GPR(request.POST) 
            if form_2.is_valid():
                model_instance = form_2.save(commit=False)
                name_object = pk
                name_working = model_instance.name_working
                type_izm = model_instance.type_izm
                value_work = model_instance.value_work
                lyudi_norma = model_instance.lyudi_norma
                technik_norma = model_instance.technik_norma
                date_begin = model_instance.date_begin
                date_end = model_instance.date_end
                new_entry = CreateNewGPR(name_object=name_object, name_working=name_working, type_izm=type_izm, value_work=value_work, lyudi_norma=lyudi_norma, technik_norma=technik_norma, date_begin=date_begin, date_end=date_end)
                new_entry.save()
                return redirect("book-detail", pk)

    context['form_category_1'] = form_category_1
    context['form_2'] = form_2

    """ Gets an individual book object from the database, based on its ID/PK. Renders a detail template """
    book = get_object_or_404(ArkiObject_1, pk=pk)

    filter_qs = CreateNewGPR.objects.filter(name_object=pk)
    filter_qs = filter_qs.values("name_working", "type_izm", "value_work", "lyudi_norma", "technik_norma", "date_begin", "date_end")

    context['books'] = filter_qs
    return render(request, 'bookdetail.html', context)

In my opinion, you can dynamically set the choices for a Django form field by overriding the form’s __init__ method and passing the choices from your view. There’s no need to use a temporary model just to store choices; you can build the choices list directly from your queryset.

Example:

Suppose you have these models:

class Category(models.Model):
    name_object = models.IntegerField()
    category_name = models.CharField()

And your form:

from django import forms
from .models import CreateNewGPR

class FormGPR(forms.ModelForm):
    class Meta:
        model = CreateNewGPR
        fields = ("name_category", "name_working", "type_izm", "value_work", "lyudi_norma", "technik_norma", "date_begin", "date_end")
        widgets = {
            "name_category": forms.RadioSelect(),
            "date_begin": forms.DateInput(attrs={"type": "date"}),
            "date_end": forms.DateInput(attrs={"type": "date"}),
        }

    def __init__(self, *args, **kwargs):
        category_choices = kwargs.pop('category_choices', [])
        super().__init__(*args, **kwargs)
        self.fields['name_category'].widget.choices = category_choices

In your view, filter and process the data as needed, then pass the choices to the form:

def book(request, pk):
    # Filter categories for this object
    categories = Category.objects.filter(name_object=pk)
    category_choices = [(cat.category_name, cat.category_name) for cat in categories]

    form = FormGPR(category_choices=category_choices)

    if request.method == 'POST':
        form = FormGPR(request.POST, category_choices=category_choices)
        if form.is_valid():
            # Save your form
            form.save()
            return redirect('some-view')

    return render(request, 'your_template.html', {'form': form})
Вернуться на верх