0

I am trying to pass a filter queryset for a Django ModelForm widget (select widget, to be precise) (from a class based view.)

Normally, I would do something like

# views.py
class MyView(SuccessMessageMixin, CreateView):
    model = MyModel
    form_class = MyCreateForm
    template_name = 'create.html'
    success_message = "You new object has been created."
    success_url = reverse_lazy('mymodel-index')

# forms.py
class MyCreateForm(forms.ModelForm):
    class Meta:  
        model = MyModel
        fields = [
            'title', 'car', # etc
        ]
        widgets = {
            'car': forms.widgets.Select(
                required=True,
                queryset=Car.objects.all(), # I need to filter this to the current user
            ),
        }

Or for non-select fields, I can pass initial data from the view class.

However, I need to filter the queryset (in the car select Widget) by the currently logged in user. I could try passing the user to __init__ from the View, but I don't know how to access that from the Meta subclass.

Any pointers in the right direction would be appreciated.

1 Answers1

0

If you are trying to add a filter to a query that uses a Select input, a good way of doing so would be to create a model with your filters, and then outputting them in a for loop in your form.

This is an example of what I use in production:

models.py

class Category(models.Model):
    name = models.CharField(max_length=50, blank=True, db_index=True)
    created = models.DateTimeField(auto_now_add=True)
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)

    def __str__(self):
        return self.name

query_page.html

<a><b>Filter by category</b></a>
                <select class="form-control" id="search_category" name="search_category">
                    <option value=""{% if value == "" %}selected {% endif %}>Any Category</option>
                    {% for category in categories %}
                    <option value="{{category.name}}"
                    {% if category.name == search_category %} selected="selected" {% endif %}>
                        {{category.name|title}}
                    </option>
                    {% endfor %}
                </select>

views.py

categories = Category.objects.all().order_by('name')
search_category = request.GET.get('search_category', '')


if search_category:
    .....
PolarBear
  • 97
  • 5
  • In this example, what if I am looking for would be similar to `categories` created by/belonging to the current user (assuming the model saves such info) – NullPointer Jan 06 '23 at 15:01
  • You would add a user field "categories", ManytoManyField, and specify the "related_name". Set null to true. This would allow each user to have no or many categories, and each category can bet set to multiple users or none – PolarBear Jan 06 '23 at 18:44