0

The Trim inherited the Car and the TrimType, and the TrimType inherited the Car.

When creating Trim on a specific Car detail page, I want to filter the queryset of trimType field by the id of the Car.

from All trimType select options

to trimType selection options for Car1

I referred to How to use the request in a ModelForm in Django.

My templates/brand/trim_update.html is:

# trim_update.html

{% extends 'base.html' %}
{% block content %}
<div class="container">
    <h5 class="my-3 border-bottom pb-2">New Trim</h5>
    <form method="post" class="post-form my-3" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn btn-primary">Save</button>
    </form>
</div>
{% endblock %}

and brand/models.py is:

# models.py

class Car(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200, null=False, blank=False)
    image = models.ImageField(default=None, null=True, upload_to='car/%Y/%m/%d/')
    order = models.IntegerField(default=0)

    def __str__(self):
        return self.name

class TrimType(models.Model):
    car = models.ForeignKey(Car, on_delete=models.SET_NULL, blank=True, null=True)
    typeName = models.CharField(max_length=50, blank=False, ull=False)

    def __str__(self):
        return self.typeName

class Trim(models.Model):
    id = models.AutoField(primary_key=True)
    order = models.IntegerField(default=0)
    trimType = models.ForeignKey(TrimType, on_delete=models.SET_NULL, null=True, blank=True)
    car = models.ForeignKey('Car', on_delete=models.SET_NULL, null=True)
    name = models.CharField(max_length=256, default='')
    price = models.IntegerField(default=0)
    image = models.ImageField(default=None, blank=True, null=True, upload_to='trim/%Y/%m/%d/')

    def __str__(self):
        if self is not None and self.car is not None:
            return self.car.name +'-'+self.name
        else: return ''

and brand/views/base_views.py is:

# base_views.py

def trim_create(request, car_id):
    if request.method == 'POST':
    car = get_object_or_404(Car, pk=car_id)
        form = TrimForm(request.POST, request.FILES, request=request)
        form.fields['trimType'].queryset = TrimType.objects.filter(car_id=car_id)
        if form.is_valid():
            trim = form.save(commit=False)
            trim.car = car
            trim.image = form.cleaned_data['image']
            trim.save()
            return redirect('brand:car_detail', car_id=car_id)
    else:
        form = TrimForm()

    context = {'form': form}
    return render(request, 'brand/trim_update.html', context)

and brand/forms/CarForms.py is:

# CarForms.py

class TrimForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        super(TrimForm, self).__init__(*args, **kwargs)
        self.fields['trimType'].queryset = TrimType.objects.filter(car=self.request.car)

    class Meta:
        model = Trim
        fields = ('id', 'name', 'price', 'order', 'trimType', 'image')
        image = forms.ImageField()

    name = forms.CharField(required=True)
    trimType = forms.ModelChoiceField(queryset=TrimType.objects.all())
    price = forms.IntegerField(required=True)
    order = forms.IntegerField(required=True)

But, The following error occurs in CarForms.py:

self.request = kwargs.pop('request')

KeyError: 'request'

JRR
  • 51
  • 1
  • 4

1 Answers1

0

I think you don't need to filter TrimType queryset in your TrimForm, because you are doing exact same thing in your trim_create view. Try this:

# base_views.py

def trim_create(request, car_id):
    if request.method == 'POST':
    car = get_object_or_404(Car, pk=car_id)
        form = TrimForm(request.POST, request.FILES, request=request)
        form.fields['trimType'].queryset = TrimType.objects.filter(car__id=car_id)
        if form.is_valid():
            trim = form.save(commit=False)
            trim.car = car
            trim.image = form.cleaned_data['image']
            trim.save()
            return redirect('brand:car_detail', car_id=car_id)
    else:
        form = TrimForm()

    context = {'form': form}
    return render(request, 'brand/trim_update.html', context)



# CarForms.py

class TrimForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(TrimForm, self).__init__(*args, **kwargs)

    class Meta:
        model = Trim
        fields = ('id', 'name', 'price', 'order', 'trimType', 'image')
        image = forms.ImageField()

    name = forms.CharField(required=True)
    trimType = forms.ModelChoiceField(queryset=TrimType.objects.all())
    price = forms.IntegerField(required=True)
    order = forms.IntegerField(required=True)
Kholdarbekov
  • 973
  • 1
  • 10
  • 28