LaVOZs

The World’s Largest Online Community for Developers

'; python - Django Queryset ManyToMany - LavOzs.Com

I'm trying to only show a user the Portfolios that they created but right now the form shows the user all the portfolios created. Ideally, I would like to filter this in the view.py but maybe filtering in the models.py could also be a good approach as I'll need this in several forms throughout the app.

A post can belong to many different portfolios. Similar to how a hiking article may belong to several categories (outdoors, fitness, nature, travel, etc.) The only thing is I only want to show the user the "categories" or in our case the Portfolios that they have created and not of other users.

I've been on this for several days now and read Djangos docs on queryset and manytomany plus gone through countless other guides and SOF questions. Am I overcomplicating this whole thing? It seems like it should be super simple.

Any help would be very much appreciated.

views.py

class PostCreate(CreateView):
    model = Post
    form_class = PostCreateForm

    def get_queryset(self):
        return Portfolio.objects.filter(user=self.request.user).order_by('created')

Models.py

class Portfolio(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=20)
    description = models.CharField(max_length=250, blank=True, null=True)

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=50)
    body = RichTextUploadingField(blank=True, null=True)
    associated_portfolios = models.ManyToManyField(Portfolio, blank=True)
    created_on = models.DateField(auto_now_add=True, editable=False)

post_form.html

{% extends 'dashboard/base.html' %}
{% block content %}
    <!-- Page Heading -->
    <div class="d-sm-flex align-items-center justify-content-between mb-4">
        <h1 class="display-4 mb-0 text-gray-800">My Posts</h1>
        <a role="button" class="btn btn-success" href=" {% url 'post-list' %} "><i
                class="fas fa-list"></i> All Posts</a>
    </div>
    <form role="form" method="post">
        {% csrf_token %}
        {{ form.media }}
        {{ form.as_p }}
        <input type="submit" class="btn btn-success" value="Create">
    </form>
{% endblock %}

I have discovered a working solution may add it as the final solution unless I run into some issues with it or we discover a better solution here. I'm not sure yet if this will work with all of my forms. Testing it with a page that uses inlineformset_factory now.

views.py

class PostCreate(CreateView):
    model = Post
    form_class = PostCreateForm

    def get_form(self, *args, **kwargs):
        form = super().get_form(*args, **kwargs)  # Get the form as usual
        user = self.request.user
        form.fields['associated_portfolios'].queryset = Portfolio.objects.filter(user=user)
        return form
Related
How to combine two or more querysets in a Django view?
How do I do a not equal in Django queryset filtering?
django - inlineformset_factory with more than one ForeignKey
writing a django query and get reverse related objects in one hit of database!
Saving form data rewrites the same row
Loop inside loop in queryset in Django template
Using Tag model to create ManytoMany relationship
Upload multiple files with one single input