Как имитировать необязательную форму администратора OneToOneField от django - PullRequest
3 голосов
/ 30 июня 2011

Я хотел бы имитировать функциональность, которую предлагает сайт администратора Django, когда модель имеет OneToOneField для другой модели, где необязательно заполнять форму для модели OneToOne. Форма для этого поля всегда отображается, но если она пуста, объект OneToOneField не создается, создается или изменяется только основной объект. Он также имеет флажок удаления, который активируется только после создания объекта OneToOneField. Если этот флажок установлен и вы нажали «Сохранить», объект OneToOne будет удален, но основной объект сохранен.

Используемые модели: одна - продукт, а другая - дополнительная информация о продукте, если это пиво:

class Producto(models.Model):
    nombre = models.CharField(max_length=100, blank=False)

class Cerveza(models.Model):
    producto = models.OneToOneField(Producto)

Вот что я пытался сделать с представлением:

def productomodificar(request, producto_id):
    from django.forms.models import inlineformset_factory
    from pdv.models import Producto, Cerveza
    from pdv.forms import ProductoForm, CervezaForm

    ProductoFormSet = inlineformset_factory(Producto, Cerveza, can_delete=True, form=CervezaForm)

    alerta = None
    producto = get_object_or_404(Producto, pk=producto_id)
    if request.user.is_staff:
        if request.method == 'POST':
            form = ProductoForm(request.POST, instance=producto)
            cervezaform = ProductoFormSet(request.POST, instance=producto)
            if form.is_valid():
                if cervezaform.is_valid():
                    form.save()
                    cervezaform.save()
                    alerta = "Producto modificado exitosamente"
                else:
                    alerta = "Error al modificar datos de cerveza"
            else:
                alerta = "Error al modificar producto"

        else:
            form = ProductoForm(instance=producto)
            cervezaform = ProductoFormSet(instance=producto)
            getm = request.GET.get('m', None)
            if getm == '1':
                alerta = "Producto creado exitosamente"
    else:
        alerta = "No tienes permiso para editar productos"
        form = producto
    c = {"user": request.user, "titulo": "Administrar Producto", "form": form, "cervezaform":cervezaform, "alerta":alerta}
    c.update(csrf(request))
    return render_to_response("productomodificar.html",c)

Это мои вовлеченные формы:

class ProductoForm(ModelForm):
    class Meta:
        from pdv.models import Producto
        model = Producto

class CervezaForm(ModelForm):
    class Meta:
        from pdv.models import Cerveza
        model = Cerveza

И вот как мне удалось показать обе формы в шаблоне:

<form method="post" action="">{% csrf_token %}
    <table>
        {{ form.as_table }}
        {{ cervezaform.as_table }}
        <tr>
            <th></th>
            <td><input type="submit" value="Guardar" /></td>
        </tr>
    </table>
</form>

Но, тем не менее, проблема в том, что я не могу добавить продукт, если я не заполняю форму OneToOne (Cerveza). Так что это не может быть пустым. Также, если я пытаюсь удалить форму OneToOne, я получаю это сообщение:

(Hidden field id) Select a valid choice. That choice is not one of the available choices.

К сожалению, мне не удалось найти хороший пример того, как создать форму для необязательного OneToOneField и использовать ее в пользовательском шаблоне.

Я оставляю здесь два примера того, как это работает в админке django:

Перед добавлением необязательного одноэлементного объекта: http://i.imgur.com/p3P6s.png

После создания необязательного одноэлементного объекта: http://i.imgur.com/UEcm8.png

Я буду очень признателен за любую помощь. Заранее спасибо.

1 Ответ

1 голос
/ 01 июля 2011

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

    alerta = "Producto modificado exitosamente"

с:

    from django.shortcuts import redirect
    return redirect('my_view')

(Вы можете перенаправить обратно в форму с помощью return redirect('pdv.views.productomodificar', prodcuto.id))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...