Как создать встроенный набор форм для отношения обратного внешнего ключа

У меня есть модель свойств следующим образом =

class Property(models.Model):
    property_type = models.CharField(max_length=255, default='Apartment')
    specifications = models.CharField(max_length=255, default='Basic')
    built_up_area = models.FloatField(max_length=6, null=False, default=0)
    total_area = models.FloatField(null=False, default=0)
    number_of_bedrooms = models.CharField(max_length=3, default=1)
    number_of_bathrooms = models.CharField(max_length=3, default=1)
    number_of_parking_spaces = models.CharField(max_length=2, default=0)
    address_line_one = models.CharField(max_length=255, null=False)
    address_line_two = models.CharField(max_length=255, null=True, default=None)
    connectivity = models.CharField(max_length=255, default=None, null=True)
    neighborhood_quality = models.CharField(max_length=255, default=None,
                                            null=True)
    comments = models.CharField(max_length=255, default=None, null=True)
    city = models.ForeignKey('City')
    state = models.ForeignKey('State')
    pin_code = models.ForeignKey('PinCode')
    developer = models.ForeignKey('Developer', null=True, default=None)
    owner = models.ForeignKey('Owner', null=True, default=None)
    created_by = models.ForeignKey('custom_user.User')

    project = models.ForeignKey('Project')

    def __unicode__(self):
        return self.property_type

    class Meta:
        verbose_name_plural = 'Properties'

И модель города следующим образом -

class City(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(City, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.name

Теперь я хочу создать единую форму, в которой я могу ввести сведения о собственности, и при вводе города я могу ввести название города вместо выбора из раскрывающегося списка.

Итак, как мне создать встроенный набор форм, используя inlineformset_factory для создания формы?

== РЕДАКТИРОВАТЬ ==

Я попытался использовать следующий код для создания набора форм

CityFormset = inlineformset_factory(City, Property,
                                       fields=('city',),
                                       extra=0,
                                       min_num=1,
                                       can_delete=False)

person utkbansal    schedule 06.07.2015    source источник
comment
Кажется, это именно тот вариант использования inlineformset_factory. Какие у вас проблемы?   -  person Daniel Roseman    schedule 06.07.2015
comment
хорошо, inlineformset_factory, похоже, работает нормально, если модель City имеет fk для PropertyModel, но не наоборот.   -  person utkbansal    schedule 06.07.2015
comment
Пожалуйста, не беспокойте меня за помощью только через 20 минут. У меня много звонков в свободное время, и я помогаю StackOverflow, когда могу. Нет ничего необычного в том, что приходится ждать несколько часов, чтобы получить ответ.   -  person Daniel Roseman    schedule 06.07.2015


Ответы (1)


Вы неправильно поняли, что такое встроенный набор форм. Он предназначен для редактирования стороны «многие» отношения «один ко многим»: то есть, учитывая родительскую модель города, вы можете редактировать различные свойства, принадлежащие этому городу.

Вы вовсе не хотите, чтобы набор форм просто редактировал один город, которому может принадлежать свойство. Вместо этого переопределите поле city в форме свойств как текстовое поле и либо создайте новый город, либо найдите существующий в методе clean_city.

class PropertyForm(forms.ModelForm):
    city = forms.TextField(required=True)

    class Meta:
        model = Property
        exclude = ('city',)

    def __init__(self, *args, **kwargs):
        super(PropertyForm, self).__init__(*args, **kwargs)
        if self.instance and not self.data:
            self.initial['city'] = self.instance.city.name

    def save(self, commit=True):
        city_name = self.cleaned_data['city']
        city, _ = City.objects.get_or_create(name=city_name)
        instance = self.save(commit=False)
        instance.city = city
        if commit = True:
            instance.save()
        return instance
person Daniel Roseman    schedule 06.07.2015
comment
Я получаю следующую ошибку проверки формы «Выберите допустимый вариант. Этот выбор не является одним из доступных вариантов. - person utkbansal; 06.07.2015
comment
Необходимо исключить существующее поле города из формы. Я обновил код. - person Daniel Roseman; 06.07.2015
comment
@DanielRoseman Спасибо, Дэниел, это многое для меня прояснило. К сожалению, это не сработало для меня, хотя у меня есть аналогичное требование. Вот мой код, если вы посмотрите на него, если у вас есть шанс. Я выделил ошибки, которые я получил по этому поводу; dpaste.de/Gkcy#L65,78,79,86,94 - person Uma; 07.08.2015
comment
вышеизложенное не сработало для меня, и мне приснился кошмар, но, наконец, я получил ответ. вот; stackoverflow.com/questions/ 31907731/ - person Uma; 09.08.2015
comment
Этот первый абзац должен быть в документации о встроенных наборах форм. Хотя это кажется очевидным после того, как вы поняли концепцию, трудно понять, как обращаться с внешними ключами с одной стороны. - person chicocvenancio; 29.12.2015