On May 18, 3:32 pm, Simon Greenwood <[email protected]> wrote:
> On May 18, 12:02 pm, Simon Greenwood <[email protected]> wrote:
>
>
>
> > On May 15, 5:58 pm, simong <[email protected]> wrote:
>
> > > There's probably a very simple answer to this but I can't see it at
> > > the moment:
>
> > > This model:
>
> > > class Product(models.Model):
> > > user = models.ForeignKey(User, related_name="product_list",
> > > editable=False)
> > > productid = models.CharField(max_length=40, blank=True)
> > > prodname = models.CharField(max_length=255, verbose_name='Product
> > > name')
> > > proddesc = models.TextField(blank=True,
> > > verbose_name='Description')
> > > prodtopcat = models.ForeignKey(ProductTopCategory,
> > > verbose_name='Product Main Category')
> > > prodsubcat = models.ForeignKey(ProductSubCategory,
> > > verbose_name='Product Sub Category')
> > > unit = models.ForeignKey(Units, verbose_name='Unit')
> > > video = models.ManyToManyField('Video', blank=True,
> > > verbose_name='Video')
> > > costperunit = models.DecimalField(max_digits=6, decimal_places=2,
> > > verbose_name='Cost per unit')
> > > costperlot = models.DecimalField(max_digits=6, decimal_places=2,
> > > verbose_name='Cost per lot')
> > > available = models.BooleanField(default=True)
> > > featured = models.BooleanField(blank=True, null=True)
>
> > > is used to generate a ModelForm with two modified fields that enable
> > > the field 'prodsubcat' to be dynamically populated based on the
> > > selection of 'prodtopcat'.
>
> > > class DynamicChoiceField(forms.ChoiceField):
> > > def clean(self, value):
> > > return value
>
> > > class ProductForm(ModelForm):
> > > prodsubcat = DynamicChoiceField(widget=forms.Select(attrs=
> > > {'disabled': 'true'}), choices =(('-1', 'Select Top Category'),))
>
> > > I took this from an item I found on the web. I think setting the
> > > 'disabled' attribute is all I actually need.
>
> > > The dynamic lookup is performed using jQuery.getJSON with this view:
>
> > > def feeds_subcat(request, cat_id):
> > > from django.core import serializers
> > > json_subcat = serializers.serialize("json",
> > > ProductSubCategory.objects.filter(prodcat = cat_id), fields=('id',
> > > 'shortname', 'longname'))
> > > return HttpResponse(json_subcat,
> > > mimetype="application/javascript")
>
> > > and the SELECT HTML is generated like this:
>
> > > options += '<option value="' + j[i].pk + '">' + j[i].fields
> > > ['longname'] + '</option>';
>
> > > This all works, but on submitting the form, I get the error 'Cannot
> > > assign "u'17'": "Product.prodsubcat" must be a "ProductSubCategory"
> > > instance' where "u'17'" is the option value of id_prodsubcat
>
> > > What type of variable should I be passing (I assume int) and where
> > > should I be converting it? In validation, in the pre-save signal, in
> > > the save signal? Or should I be trying to convert it on the form
> > > itself? Where is the ForeignKey instance save process documented?
>
> > To bump this and to add more detail: now, when I attempt to save the
> > form, I am getting the error 'Cannot assign "u'266'":
> > "Product.prodsubcat" must be a "ProductSubCategory" instance.' where
> > 266 is the primary key of the ProductSubCategory object selected from
> > a list that is looked up by the selection of a ProductTopCategory
> > option as shown in the Product model above. How can I return a
> > ProductSubCategory instance from the variable at form save time?
>
> To answer myself, this
> post:http://monogroncho.com/2008/10/django-gotchas-part-1/
> is exactly what I was looking for, although the code as given seems
> rather inelegant and gives me the AttributeError 'list' object has no
> attribute 'widget'. My feeling is that I don't have to be returning a
> list of ProductSubCategory objects, just the one that my choice
> represents. Does anyone have a view on this? I can't be the only
> person combining django and Ajax in this way.
>
This is a sort of solution: A ChoiceField is populated at render time
by data either called from the ModelForm relationship or from a
ModelChoiceField lookup, and populates the HTML select field on the
form. It is this instance that is validated. Populating the choices
dictionary therefore deletes the data from the lookup:
class ProductForm(ModelForm):
prodsubcat = forms.ModelChoiceField(ProductSubCategory.objects,
widget=forms.Select(attrs={'disabled': 'true'}), choices =(('-1',
'Select Top Category'),))
and breaks the validation.
If the field is rendered without the choices dictionary, but with the
'disabled' attribute, it will display as a disabled select field.
Selecting an option from the prodtopcat select field calls the Ajax
lookup, which populates the prodsubcat field with filtered data in the
browser, but not in the field object. Selecting a category from the
prodsubcat field returns an option that can be validated from the
field object.
Simon
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---