def save(self): ''' Extends the base save by saving the cleaned location entry and adding it to the ModelForm's internal place. commit=False is not supported. Supporting this may require emulating how Django handles defering m2m saving for the tags since we're not having hte ModelForm handle them directly. ''' place = super(OrgAdminPlaceForm, self).save(commit=False) # process location location = self.cleaned_data['location'] location.save() place.location = location place.hours = [] for i in range(1, 8): day = self.cleaned_data.get('hr_days_%d' % i, '') hrs = self.cleaned_data.get('hr_hours_%d' % i, '') if day or hrs: place.hours.append(HoursListing(day, hrs)) parking_obj = Parking() for opt in self.cleaned_data['parking']: parking_obj.add_option(opt) place.set_parking(parking_obj) if place.id is None: place.save() # save if new now so we can add m2m # handle tags manually new_tags = self.cleaned_data['tags'] # save all the tags that aren't in the DB yet [t.save() for t in new_tags if t.id is None] # safe to make a set now, all Tags have a unique ID new_tags = set(new_tags) # figure out which tags need to be added and removed existing_tags = set(place.tags.all()) # remove all tags that didn't get submitted in the form [place.tags.remove(tag_to_rm) for tag_to_rm in existing_tags.difference(new_tags)] # add all new tags [place.tags.add(tag_to_add) for tag_to_add in new_tags.difference(existing_tags)] place.save() return place
def get_parking(self): '''returns a places.models.Parking object''' # first do a sanity check on the hours to ensure they're in the format we expect # will raise a ValueError is the format is off fb_parking = self.data.get('parking') if fb_parking is None: return None if not hasattr(fb_parking, 'items'): raise ValueError('Unexpected format for "parking"') p = Parking() for k, v in fb_parking.items(): if not isinstance(k, basestring) or len(k) == 0: raise ValueError('Unexpected format for "parking"') try: int(v) # could use bool here, but don't want to OK any random string except TypeError, ValueError: raise ValueError('Unexpected format for "parking"') if bool(v): p.add_option(k)