Nick Bewley
Nick Bewley

Reputation: 9289

Django Forms from Models

I am trying to integrate an app called Django-Classifieds, but am having trouble figuring out how to manipulate some of the elements.

The app allows one to create a category and subfields through the admin section, which will be displayed and allow the user to create a post within said category. Although the Django admin allows one to create fields:

DJango Admin

And writes them to the database:

enter image description here

I cannot figure out how to call these fields and display them to the user. Currently, only the title field is displayed. I understand that using ModelForm will allow me access to these elements, but I'm not sure how to incorporate it with BaseForm (used by in the app as below):

class AdForm(BaseForm):
  def __init__(self, instance, data=None, files=None, auto_id='id_%s', prefix=None,
                         initial=None, error_class=ErrorList, label_suffix=':',
                         empty_permitted=False):

    self.instance = instance
    object_data = ad_to_dict(self.instance)
    self.declared_fields = SortedDict()
    self.base_fields = fields_for_ad(self.instance)

    # if initial was provided, it should override the values from instance
    if initial is not None:
        object_data.update(initial)

    BaseForm.__init__(self, data, files, auto_id, prefix, object_data,
                      error_class, label_suffix, empty_permitted)

  def save(self, commit=True):
    if not commit:
        raise NotImplementedError("AdForm.save must commit it's changes.")

    if self.errors:
        raise ValueError("The ad could not be updated because the data didn't validate.")

    cleaned_data = self.cleaned_data

    # save fieldvalues for self.instance
    fields = field_list(self.instance)

    for field in fields:
        if field.enable_wysiwyg:
            value = unicode(stripHTML(cleaned_data[field.name]))
        else:
            value = unicode(cleaned_data[field.name])

        # strip words in settings.FORBIDDEN_WORDS
        for word in settings.FORBIDDEN_WORDS:
            value = value.replace(word, '')

        # title is stored directly in the ad, unlike all other editable fields
        if field.name == 'title':
            self.instance.title = value
            self.instance.save()
        else:
            # check to see if field.fieldvalue_set has a value with ad=self.instance
            try:
                # if it does, update
                fv = field.fieldvalue_set.get(ad=self.instance)
            except FieldValue.DoesNotExist:
                # otherwise, create a new one
                fv = field.fieldvalue_set.create(ad=self.instance)

            # XXX some ugly price fixing
            if field.name.endswith('price'):
                m = re.match('^\$?(\d{1,3},?(\d{3},?)*\d{3}(\.\d{0,2})?|\d{1,3}(\.\d{0,2})?|\.\d{1,2}?)$', value)
                value = m.group(1)
                value.replace(',', '')
                value = '%.2f' % float(value)

            fv.value = value
            fv.save()

    return self.instance

How can I display all created fields in the AdForm above?

Any examples appreciated. Thank you.

Upvotes: 0

Views: 258

Answers (1)

saebyn
saebyn

Reputation: 26

Incorporating ModelForm isn't needed, since the purpose of the AdForm class is to allow access to those fields. In order to display the custom fields added to a category in the database, all that is needed is to add the fields to the templates for the appropriate category (assuming you are using the views provided in the app). There are examples of this in the "base" category templates within the classifieds app.

Upvotes: 1

Related Questions