Django формирует способ отображения связанных данных во внутренней форме - PullRequest
0 голосов
/ 01 марта 2020

Я борюсь с Django формами. У меня есть следующий model.py:

class Property(models.Model):
    portfolio = models.ForeignKey("portfolios.Portfolio", on_delete=models.CASCADE)


class PropertyImage(models.Model):
    property = models.ForeignKey("Property", on_delete=models.CASCADE)
    image = models.ImageField(upload_to = property_image_upload_to)

    def __str__(self):
        return self.image.url


class PropertyDocument(models.Model):
    property = models.ForeignKey("Property", on_delete=models.CASCADE)
    document = models.FileField()


class Address(models.Model):
    property = models.OneToOneField("Property", on_delete=models.CASCADE)
    line1 = models.CharField(max_length=100)
    line2 = models.CharField(max_length=100, null=True, blank=True)
    line3 = models.CharField(max_length=100, null=True, blank=True)
    post_code = models.CharField(max_length=7)
    town = models.CharField(max_length=100, null=True, blank=True)
    city = models.CharField(max_length=100)

При добавлении / обновлении свойства я хочу, чтобы форма отображала форму для связанных объектов, таких как адрес, документы / изображения вместо списка выбора, который появляется в формы - я хочу иметь возможность добавлять / редактировать связанные данные.

Мой файл view.py

class PropertyCreate(CreateView):
    model = Property
    form_class=PropertyAddressFormSet
    success_url = reverse_lazy('Property_list')

    def get_context_data(self, **kwargs):
        data = super(PropertyCreate, self).get_context_data(**kwargs)
        return data

Property_form. html

{% extends 'base/base.html' %}
{% load crispy_forms_tags %}

{% block content %}

<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit" class="btn btn-primary" />
    <button class="btn btn-link" onclick="javascript:history.back();">Cancel</button>
</form>

{% endblock %}

urls .py

from . import views

app_name = 'properties'
urlpatterns = [
    path('<int:portfolio_id>/<int:pk>/edit', views.PropertyUpdate.as_view(), name='property_edit'),
    path('<int:portfolio_id>/create', views.PropertyCreate.as_view(), name='property_new'),
]

Я читал об inlineformset_factories и inlineformset's et c, но лучше ли это для моего сценария? Если это так, я не могу понять, как отобразить портфолио, адресная форма

Я в настоящее время использую встроенный набор, например, который создает форму Address в представлении PropertyCreate, но я также хочу добавить в PropertyImages и PropertyDocs в представлении ProertyCreate .:

PropertyAddressFormSet = inlineformset_factory(
    parent_model=Property, 
    model=Address, 
    form=AddressForm, 
    extra=0,
    min_num=1
)

1 Ответ

0 голосов
/ 16 марта 2020

Для любого человека, находящегося в той же лодке, что и я, мне удалось заставить его работать со следующим кодом:

Forms.py:

class PropertyForm(ModelForm):
    """ Edit a property """
    class Meta:
        model = Property
        exclude = ()

PropertyAddressFormSet = inlineformset_factory(
    parent_model=Property, 
    model=Address, 
    form=AddressForm, 
    extra=0,
    min_num=1
)

Views.py

class PropertyCreate(CreateView):
    model = Property
    form_class=PropertyForm
    success_url = reverse_lazy('Property_list')

    def get_context_data(self, **kwargs):
        data = super(PropertyCreate, self).get_context_data(**kwargs)
        if self.request.POST:
        data['address'] = PropertyAddressFormSet (self.request.POST, instance=self.object)
    else:
        data['address'] = PropertyAddressFormSet ()
    return data

шаблон:

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form |crispy }}
    <fieldset class="border p-2">
        <legend class="w-auto">Address</legend>
        {{ address.management_form }}
        {% for form in address.forms %}
        <div >
            {{ form.as_p }}
        </div>
        {% endfor %}
    </fieldset>
</form>

Надеюсь, это кому-нибудь поможет.

...