скопировать значения нескольких ModelMutipleChoiceField в одно после Post с использованием MPTT - PullRequest
0 голосов
/ 03 октября 2018

Я боролся с этой проблемой весь день и надеюсь, что кто-нибудь может помочь.Все мои иерархии классифицированы по категориям в одной таблице.во время создания формы я хочу разделить каждую иерархию по категориям и отобразить ее с помощью ModelMutipleChoiceField, чтобы не все иерархии отображались вместе.

Проблема возникает при отправке формы, так как мне нужно пройти через каждуюПоле ModelMutipleChoiceField и получите выбранные значения и скопируйте их в поле модели перед сохранением формы.Тем не менее, я не могу перебрать ModelMutipleChoiceField и получить выбранные значения.Я также не знаю, как установить эти значения в ModelField

ПРИМЕЧАНИЕ: Количество иерархий может варьироваться.

вот мой код:

Я использую Django MPTT и создаю свою иерархическую структуру, используя 2 модели.одна - это категория (Hierarchy), а другая - узлы иерархии (HierarchyNode_MPTT).

Затем я создал отдельную модель, в которой ManyToManyField указывает на HierarchyNode_MPTT.

Модели.py

class Hierarchy(models.Model):
    ID = kp.ObjectIDField()
    name = kp.ObjectNameField()
    ext_hierarchy = kp.ObjectTechnicalID()
    seq_no = kp.SeqNoField(unique=True)
    mptt_seq_no = models.PositiveIntegerField()

class HierarchyNode_MPTT(MPTTModel):
    id = kp.ObjectIDField()
    name = kp.ObjectNameField()
    description = kp.ObjectDescriptionField()
    ext_node_id = kp.ObjectShortNameField()
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
    hierarchy = models.ForeignKey(Hierarchy, on_delete=models.CASCADE, null=True, blank=True, related_name='children')

class Configuration(models.Model):
    uuid = kp.ObjectIDField()
    name = kp.ObjectNameField()
    description = kp.ObjectDescriptionField()
    hierarchy_nodes = models.ManyToManyField(HierarchyNode_MPTT)       

Затем я создал форму и реализовал метод init , чтобы автоматически создавать столько иерархий, сколько мне нужно. Форма

.py

class ConfigurationCreateForm(forms.ModelForm):
    class Meta:
        model = ForecastConfiguration
        exclude = ['uuid', 'hierarchy_nodes']

    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)

        hierarchies = Hierarchy.objects.all()
        for hierarchy in hierarchies:
            field_name = 'hierarchy_%s' % (hierarchy.mptt_seq_no,)
            self.fields[field_name] = TreeNodeMultipleChoiceField(queryset=HierarchyNode_MPTT.objects.all().filter(hierarchy=hierarchy),label=hierarchy.name, required=True)
            try:
                self.initial[field_name] = HierarchyNode_MPTT.objects.root_node(tree_id=hierarchy.mptt_seq_no)

            except IndexError:
                self.initial[field_name] = ''

    def copy_hierarchies(self, *args, **kwargs):
        hierarchies = Hierarchy.objects.all()
        choice_list = list()
        for hierarchy in hierarchies:
            field_name = 'hierarchy_%s' % (hierarchy.mptt_seq_no,)
            selected_values = self.cleaned_data.get(field_name)
            for selection in selected_values:
               choice_list.append(selection) 

        self.initial['hierarchy_nodes'] = choice_list

Наконец, идея заключалась в том, чтобы реализовать метод post в представлении для циклического создания созданных иерархий, а затем присвоить значение полю модели, называемому «ierarchy_nodes »

view.py

class ConfigurationCreateView(CreateView):
    model = Configuration
    form_class = ConfigurationCreateForm
    template_name = 'frontend/base/config_create.html'

    def get(self, request, *args, **kwargs):
        form = ConfigurationCreateForm(user=request.user)
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        form.copy_hierarchies(*args, **kwargs)

        if form.is_valid():
            fcc_form = form.save(commit=True)
            messages.add_message(self.request, messages.INFO, 'Your Forecast Configurations has been saved')
            return redirect(reverse('planning_detail', kwargs={'uuid': self.fcc_form.uuid}))
        else:
            messages.add_message(self.request, messages.ERROR, 'Error when creating the Forecast Configuration')
            return render(request, self.template_name, {'form': form})

Как вы можете видеть, я создал в своей форме метод с именем copy_hierarchies, в который я планировал копировать значения иерархии, это метод, в которомУ меня проблемы.

Если есть более простой способ сделать это с помощью Javascript, я открыт для этих опций.

Заранее спасибо.

1 Ответ

0 голосов
/ 18 октября 2018

Мне не удалось решить эту проблему с помощью поля с несколькими вариантами выбора, однако, вот решение для ChoiceField (одиночный выбор)

1) Изменен мой метод post view.py для сохранения объекта,2) После того, как модель сохранена, я перебираю поля ввода запроса и добавляю значения к созданному экземпляру.3) Сохраните экземпляр.4) удалить мой метод copy_hierarchies в forms.py

, вот фрагмент кода, созданный в views.py

def post(self, request, *args, **kwargs):
    form = self.form_class(request.POST)

    if form.is_valid():
        fcc = form.save()
        for key in self.request.POST:
            # check only the ones w/ 'hierarchy_#'
            if key.startswith('hierarchy_'):
                # get form field object
                id = self.request.POST[key]
                node = HierarchyNode_MPTT.objects.get(id=id)
                # add to object instance
                fcc.hierarchy_nodes.add(node)

            fcc.save()
...