Получить список связанных объектов в Django - PullRequest
0 голосов
/ 02 января 2019

У меня есть 3 модели:

class Node(models.Model):
    ID = models.DecimalField(max_digits=19, decimal_places=10)
    name = models.CharField(default='node', max_length=32)
    connexion = models.CharField(max_length=255)
    # Many2one fields | Foreign keys:
    firm = models.ForeignKey('firme.Firme', on_delete=models.CASCADE, null=True, blank=True)


class ScheduledAction(models.Model):
    date = models.DateTimeField(default=datetime.now, blank=True)
    firm = models.ForeignKey('firme.Firme', on_delete=models.CASCADE, null=True, blank=True)
    node_ids = models.ManyToManyField(Node)

Я хочу, чтобы в форме ScheduledAction для выбранной фирмы был показан список связанных с ней узлов. Обычно я должен сделать это по get:

class ScheduledActionForm(forms.ModelForm):
    date = forms.DateTimeField()
    firm = forms.ModelChoiceField(queryset=Firme.objects.all())
    node_ids = forms.ModelMultipleChoiceField(queryset=Node.objects.get(firm_id=firm.id), widget=forms.CheckboxSelectMultiple)

    class Meta:
        model = ScheduledAction
        fields = [
            'date',
            'firm',
            'node_ids'
        ]

Это мои views.py:

def planification_view(request, id):
    scheduledAction = ScheduledActionForm(request.POST or None)
    firme = get_object_or_404(Firme, id=id)
    nodes = Node.objects.all()
    if scheduledAction.is_valid():
        scheduledAction.save()
        print('formulaire enregistre')
        scheduledAction = ScheduledActionForm()
    context = {
        'firme': firme,
        'form': scheduledAction,
        'nodes': nodes
    }
    return render(request, "node/planification.html", context)

Но я получил эту ошибку:

AttributeError: 'ModelChoiceField' object has no attribute 'id'

Как я могу это исправить?

1 Ответ

0 голосов
/ 02 января 2019

В вашем подходе есть несколько неправильных вещей

в первую очередь: вы присвоили переменную 'firm' полю формы, а затем, используя эту же переменную для получения объекта из БД, работать не будуттем не мение.Переменная 'firm' в Node.objects.get(firm_id=firm.id) должна быть экземпляром фирмы.

секунда: queryset=Node.objects.get(firm_id=firm.id) не будет работать, потому что Model.objects.get () вернет объект, а не набор запросов.

Если вы хотите показать все узлы для конкретной Фирмы, вам необходимо передать объект фирмы (или идентификатор или другой идентификатор) в форму, например, передав его через get_form_kwargs(), есливы используете CBV и фильтруете по нему Node.objects.filter(firm_id=firm.id)

Обновление: Поскольку вы используете представления на основе функций, может быть более сухой способ сделать это, но я привык только кработать с CBV, поэтому я постараюсь изо всех сил

В форме мы объявим новую переменную с именем firme (мы передадим это в форму, по вашему мнению)

class ScheduledActionForm(forms.ModelForm):

def __init__(self, *args, **kwargs):
    self.firme = kwargs.pop('firme')
    super(ScheduledActionForm, self).__init__(*args, **kwargs)
    self.fields['node_ids'].queryset = Node.objects.filter(firm_id=self.firme.id)

date = forms.DateTimeField()
firm = forms.ModelChoiceField(queryset=Firme.objects.all()) # why do you want a list of all firms here? Or do you want a single object?
node_ids = forms.ModelMultipleChoiceField(queryset=Node.objects.none()), widget=forms.CheckboxSelectMultiple)

class Meta:
    model = ScheduledAction
    fields = [
        'date',
        'firm',
        'node_ids'
    ]

сейчас дляВы видите:

def planification_view(request, id):
firme = get_object_or_404(Firme, id=id)
nodes = Node.objects.all()
if request.method == 'POST':
    form = ScheduledActionForm(data=request.POST, firme=firme)
    if form.is_valid():
        scheduledAction = form.save()
        print('formulaire enregistre')
else:
    form = ScheduledActionForm(firme=firme)

context = {
    'firme': firme,
    'form': form,
    'nodes': nodes
}
return render(request, "node/planification.html", context)

Что-то в этом духе должно вас заставить.Может потребоваться некоторая настройка, чтобы заставить его работать в вашем проекте.Если у вас все еще есть проблемы с пониманием, пожалуйста, прочитайте Django docs и или выполните их учебное пособие

Обновление 2: Не самое красивое решение, но оно работает для OP

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...