Home > front end >  Django Form "'ForwardManyToOneDescriptor' object has no attribute 'all'&quo
Django Form "'ForwardManyToOneDescriptor' object has no attribute 'all'&quo

Time:05-23

Hey so I'm having quite some problems. In effect trying to add a form to a home-page with options for a user to select based on a DB object. Then once submitted the page will refresh, and the form can be used again.

Forms.py

rom django import forms
from django.forms import ChoiceField, ModelForm, RadioSelect
from .models import command_node


class command_form(ModelForm):
    class Meta:
        model = command_node
        fields = (
            'host_id',
            'current_commands'
        )

        host_id = forms.ModelChoiceField(
            required=True,
            queryset=command_node.host_id,
            widget=forms.Select(
                attrs={
                    'class': 'form-control'
                },
            )
        )

        current_comamnds = forms.ChoiceField(
            required=True,
            attrs={
                'class': 'form-control'
            },
            
            choices=[
                ('Sleep', "Sleep"),
                ('Open SSH_Tunnel', 'Open SSH_Tunnel'),
                ('Close SSH_Tunnel', 'Close SSH_Tunnel'),
                ('Open TCP_Tunnel', 'Open TCP_Tunnel'),
                ('Close TCP_Tunnel', 'Close TCP_Tunnel'),
                ('Open Dynamic', 'Open Dynamic'),
                ('Close Dynamic', 'Close Dynamic'),
                ('Task', 'Task'),
            ])

Models.py

from tkinter import CASCADE
from turtle import update
from django.db import models

class beacon(models.Model):
    host_id = models.BigAutoField('Id', primary_key=True)
    hostname = models.CharField('Hostname', max_length=200)
    internalIp = models.CharField('Internal-IP', max_length=200)
    externalIp = models.CharField('External-IP', max_length=200)
    current_user = models.CharField('Current_User', max_length=200)
    os = models.CharField('OS', max_length=200)
    admin = models.CharField('Admin', max_length=200)
    
    def __str__(self):
        return self.hostname

class command_node(models.Model):
    host_id = models.ForeignKey(beacon, on_delete=models.CASCADE)
    current_commands = models.CharField('current_command', max_length=50, null=True)
    previous_commands = models.CharField('previous_commands', max_length=2000, null=True)
    
    def __str__(self):
        return str(self.host_id)

views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import beacon
from .models import command_node
from .forms import command_form
from django.http import HttpResponseRedirect

def home(request):
    form = command_form,
    if request.method == "POST":
            form = form(request.POST)
            if form.is_valid():
                form.save()
                return render(request, 'home.html', context)
    context = {'form':form},
    return render(request, 'home.html', context)

relevant HTML section

</br>
</br>
    <form action="" method=POST>
        {% csrf_token %}
        {{ form.as_p }}
        {{form}}
        <button type="Submit" >Submit</button>
    </form>
</body>
</html>

urls.py

from django.contrib import admin
from django.urls import path
from django.urls import include, re_path
from .forms import command_node
from . import views

urlpatterns = [
    re_path('home/', views.home)
]

When I attempt to run the server or even now migrate I get the following.

PS C:\Python-projects\commandsite> python manage.py makemigrations
Traceback (most recent call last):
  File "C:\Python-projects\commandsite\manage.py", line 22, in <module>
    main()
  File "C:\Python-projects\commandsite\manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\base.py", line 414, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\base.py", line 455, in execute
    self.check()
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\management\base.py", line 487, in check
    all_issues = checks.run_checks(
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\checks\urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\checks\urls.py", line 24, in check_resolver
    return check_method()
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\urls\resolvers.py", line 480, in check
    for pattern in self.url_patterns:
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\utils\functional.py", line 49, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\urls\resolvers.py", line 696, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\utils\functional.py", line 49, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\urls\resolvers.py", line 689, in urlconf_module
    return import_module(self.urlconf_name)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "C:\Python-projects\commandsite\commandsite\urls.py", line 22, in <module>
    re_path('website/', include('website.urls'))
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\urls\conf.py", line 38, in include
    urlconf_module = import_module(urlconf_module)
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "C:\Python-projects\commandsite\website\urls.py", line 4, in <module>
    from .forms import command_node
  File "C:\Python-projects\commandsite\website\forms.py", line 6, in <module>
    class command_form(ModelForm):
  File "C:\Python-projects\commandsite\website\forms.py", line 7, in command_form
    class Meta:
  File "C:\Python-projects\commandsite\website\forms.py", line 14, in Meta
    host_id = forms.ModelChoiceField(
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\models.py", line 1463, in __init__
    self.queryset = queryset
  File "C:\Users\Admin\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\models.py", line 1488, in _set_queryset
    self._queryset = None if queryset is None else queryset.all()
AttributeError: 'ForwardManyToOneDescriptor' object has no attribute 'all'
PS C:\Python-projects\commandsite>

This was all working before I attempted to add a form in. Since tinkering with it to try and get a form this is the issue I face. So any help would be Greatly appericated. As I don't know what I've done wrong.

CodePudding user response:

Looking at your code, the error is raised because you're specifying queryset=command_node.host_id in your form:

    host_id = forms.ModelChoiceField(
        required=True,
        queryset=command_node.host_id,
        widget=forms.Select(
            attrs={
                'class': 'form-control'
            },
        )
    )

Actually, command_node.host_id is a ForwardManyToOneDescriptor (this is the class assigned to fields that are marked as ForeignKey). In this case, what you want to supply as the queryset parameter is a set of objects that should belong to the model beacon which is the onea associated to host_id:

    host_id = forms.ModelChoiceField(
        required=True,
        queryset=beacon.objects.all(),
        widget=forms.Select(
            attrs={
                'class': 'form-control'
            },
        )
    )

This will display all beacon objects in your DB as options in a dropsdown in your form (the widget used is a Select). You could also display any queryset related to the beacon model. For example if you wanted to display only the beacon objects that have an internal IP equal to X.Y.Z.W you could sepecify queryset=beacon.objects.filter(internalIP="X.Y.Z.W").

Some things to note here:

  • Django already uses a ModelChoiceField when displaying the available options for fields that rely on a ForeignKey. You can check the associations Django makes between Model fields and Form fields here: https://docs.djangoproject.com/en/4.0/topics/forms/modelforms/#field-types. If you want all beacon objects to be able for selection in your form, your code could be simplified to:
class command_form(ModelForm):
    class Meta:
        model = command_node
        fields = (
            'host_id',
            'current_commands'
        )

        current_comamnds = forms.ChoiceField(
            required=True,
            attrs={
                'class': 'form-control'
            },
            
            choices=[
                ('Sleep', "Sleep"),
                ('Open SSH_Tunnel', 'Open SSH_Tunnel'),
                ('Close SSH_Tunnel', 'Close SSH_Tunnel'),
                ('Open TCP_Tunnel', 'Open TCP_Tunnel'),
                ('Close TCP_Tunnel', 'Close TCP_Tunnel'),
                ('Open Dynamic', 'Open Dynamic'),
                ('Close Dynamic', 'Close Dynamic'),
                ('Task', 'Task'),
            ])
  • Related