【问题标题】:Filter fields queryset in Django ModelChoiceField with external reference keys使用外部引用键过滤 Django ModelChoiceField 中的字段查询集
【发布时间】:2021-10-16 07:27:59
【问题描述】:

Trim 继承了 CarTrimType 以及 TrimType > 继承了Car

在特定的 Car 详细信息页面上创建 Trim 时,我想过滤 trimType 字段的查询集Car 的 ID。

来自All trimType select options

trimType selection options for Car1

我提到了How to use the request in a ModelForm in Django

我的 templates/brand/trim_update.html 是:

# 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 %}

brand/models.py 是:

# 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 ''

brand/views/base_views.py 是:

# 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)

brand/forms/CarForms.py 是:

# 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)

但是,CarForms.py中出现以下错误:

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

KeyError: '请求'

【问题讨论】:

  • 我相信pop() 需要一个整数而不是字符串。

标签: python html django forms modelchoicefield


【解决方案1】:

我认为您不需要在 TrimForm 中过滤 TrimType 查询集,因为您在 trim_create 视图中执行完全相同的操作。试试这个:

# 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)

【讨论】:

    猜你喜欢
    • 2013-03-14
    • 2019-02-17
    • 2013-09-17
    • 1970-01-01
    • 2011-12-25
    • 2020-10-22
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多