Создание модели и связанных моделей со Встроенным formsets

Посмотрите мой подробный ответ на очень похожий предыдущий вопрос

, @Beau Crawford является хорошим путем в SQL 2005 и ниже, хотя, если Вы предоставляете представителю, это должно перейти в первый парень к ТАК этому . Единственная проблема состоит в том, что для вставок это - все еще две операции IO.

мс Sql2008 представляет merge из стандарта SQL:2003:

merge tablename with(HOLDLOCK) as target
using (values ('new value', 'different value'))
    as source (field1, field2)
    on target.idfield = 7
when matched then
    update
    set field1 = source.field1,
        field2 = source.field2,
        ...
when not matched then
    insert ( idfield, field1, field2, ... )
    values ( 7,  source.field1, source.field2, ... )

Теперь это - действительно всего одна операция IO, но ужасный код:-(

42
задан Alasdair 8 February 2016 в 11:33
поделиться

2 ответа

Сначала создайте форму модели автора.

author_form = AuthorModelForm()

затем создайте фиктивный объект автора:

author = Author()

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

formset = BookFormSet(instance=author)  #since author is empty, this formset will just be empty forms

Отправьте это на шаблон. После того, как данные возвращены обратно в представление, вы создаете автора:

author = AuthorModelForm(request.POST)
created_author = author.save()  # in practice make sure it's valid first

Теперь подключите встроенный набор форм к вновь созданному автору и затем сохраните:

formset = BookFormSet(request.POST, instance=created_author)
formset.save()   #again, make sure it's valid first

изменить:

Чтобы не было флажков в новых формах, выполните это шаблон:

{% for form in formset.forms %}
    <table>
    {% for field in form %}
        <tr><th>{{field.label_tag}}</th><td>{{field}}{{field.errors}}</td></tr>
    {% endfor %}

    {% if form.pk %} {# empty forms do not have a pk #}
         <tr><th>Delete?</th><td>{{field.DELETE}}</td></tr>
    {% endif %}
    </table>
{% endfor %}
38
ответ дан 26 November 2019 в 23:41
поделиться

models.py (Контакт)

class Contact(models.Model)
    first = models.CharField(max_length=30)
    middle = models.CharField('M.I.',max_length=30, blank=True)
    last = models.CharField(max_length=30)
    sort_order = models.PositiveIntegerField(default=99)

models.py (Ссылка)

class Link(models.Model):
    contact = models.ForeignKey(Contact)
    link = models.URLField()
    description = models.CharField(max_length=30)
    access_date = models.DateField(blank=True,null=True)

forms.py

from django.forms import ModelForm
from contacts.models import Contact

class ContactAjaxForm(ModelForm):
    class Meta:
        model=Contact

views.py

def edit(request,object_id=False):
    LinkFormSet = inlineformset_factory(Contact, Link, extra=1)
    if object_id:
        contact=Contact.objects.get(pk=object_id)
    else:
        contact=Contact()
    if request.method == 'POST':
        f=forms.ContactAjaxForm(request.POST, request.FILES, instance=contact)
        fs = LinkFormSet(request.POST,instance=contact)
        if fs.is_valid() and f.is_valid():
            f.save()
            fs.save()
            return HttpResponse('success')
    else:
        f  = forms.ContactAjaxForm(instance=contact)
        fs = LinkFormSet(instance=contact)
    return render_to_response(
        'contacts/edit.html', 
        {'fs': fs, 'f': f, 'contact': contact}
    )

Это не основанный на примере в книге, он отредактирован из некоторого кода на моем сайте. Я не тестировал его, поэтому могут быть некоторые ошибки, но в целом он должен быть надежным. Использование пустого экземпляра Contact не является рекомендуемым методом, но он экономит немного логики и работает.

Изменить:

9
ответ дан 26 November 2019 в 23:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: