Home > OS >  Assigning a queryset to a M2M field in Django results in "'ManyRelatedManager' object
Assigning a queryset to a M2M field in Django results in "'ManyRelatedManager' object

Time:10-06

# View

@require_POST
def update_category_filter(request):
    """
    Updates the Category filter
    """
    # User logged in?
    if request.user.is_authenticated:

        # Get the form instance
        filter_form = SelectCategoryForm(request.POST)

        # Form validation
        if filter_form.is_valid():

            # Check if user already has a filter instance
            instance_exists = UserCategoryFilter.objects.filter(user=request.user)

            # Get the cleaned data
            selection = filter_form.clean()
            list(selection)
            print(selection)

            # If not create, else update
            if not instance_exists:
                filter_instance = UserCategoryFilter.objects.create(user=request.user)
                print(filter_instance)

                # Add each selected filter of queryset to model instance
                for member in selection:
                    filter_instance.categories_selected.category.add(member)    # breaks here 

The selection is a clean queryset, which I want to populate the many-to-many field with. However, this results in

'ManyRelatedManager' object has no attribute 'category'

# Model

class UserCategoryFilter(models.Model):
    """
    Saves the selected category filter by a user
    """
    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    categories_selected = models.ManyToManyField(Category)

class Category(models.Model):
    """
    Model to define categories and their color styles
    """
    category = models.CharField(max_length=30)
# Form

class SelectCategoryForm(forms.Form):
    """
    A form to update category filters for logged in users
    """
    choices = forms.ModelMultipleChoiceField(queryset=Category.objects.all().order_by('category'),
                                             widget=forms.CheckboxSelectMultiple)

CodePudding user response:

As the error suggests, categories_selected is a manager so to add a category it should just be:

for member in selection['choices']:
    filter_instance.categories_selected.add(member)

or to do it without a loop:

filter_instance.categories_selected.add(*selection['choices'])

But this will only work if selection is a list of Category objects.

  • Related