简体   繁体   中英

Django OneToOne field as a dropdown in a form

I have two models related like this:

class Report(Model):
    ...
    product_line = models.OneToOneFiled(ProductLine)

class ProductLine(Model):
    name = models.CharField()
    ...

I want users to upload a report and specify which product line it belongs to. The product line field should be a dropdown list with predefined product names in it.

My question is how to render this field and how to analysis the value posted back.

Rendering

For rendering, I guess I can do this:

render():
    allProducts = ProductLine.objects.all() // side question: how to cache this queryset for repeated use?
    names = []
    for p in allProducts:
        names.push(p.name)
    return render(..., {'names': names})

Inside the template, I can loop over names and populate the items of the dropdown list. Am I correct?

Saving

When saving:

postHandler():
    // This is the part I am not so sure
    // Since the value for the product line field will be a string
    // I guess I cannot rely on a form object to validate it and expect
    // it to pass, am I correct?
    // so when I create a form out of ProductLine, I should use
    // a customized validator instead:

class ReportForm(Form):
    class Meta:
        model = Report

    clean_product_line():
        cd  = self.cleaned_data

        allProducts = ProductLine.objects.all()
        valid_names = []
        for p in allProducts:
            valid_names.push(p.name)

        if cd in valid_names:
            return allProducts.filter(name=cd)[0]

        raise ValidationError('Invalid product name')

Is this approach correct? Is clean_product_line the right place for validation and returning a model object back?

A much simpler way would be to add an extra field for the product line to the form definition:

class ReportForm(ModelForm):
    product_line = forms.ModelChoiceField(queryset=ProductLine.objects.all())

That will automatically take care of displaying and validating the dropdown. You'll need to manually set the field on the instance after saving though, using the value from cleaned_data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM