添加值以清空ModelForm

时间:2014-10-09 15:16:33

标签: django django-models django-forms

我有一个模型可以为默认用户模型添加额外的属性

class Perfil(models.Model):
    usuario = models.OneToOneField(User)
    telefono = models.CharField(max_length=140,null=True,blank=True)
    departamento = models.ForeignKey(Departamento,null=True,blank=True)
    menus = models.ManyToManyField(Menu,null=True,blank=True)
    def __unicode__(self):
        return self.usuario.username 

我有ModelForms来创建一个新用户

class UsuarioForm(ModelForm):
    class Meta:
        model = User
        fields = ("username","password","first_name","last_name","email","is_active",)

class PerfilForm(ModelForm):
    class Meta:
        model = Perfil
        exclude = ("usuario",)

我的视图看起来像这样。

def nuevo_usuario(request):
    if request.method == 'POST':
        form = UsuarioForm(request.POST, prefix='user')
        form2 = PerfilForm(request.POST, prefix='perfil')
        if form.is_valid() * form2.is_valid():
            menus = request.POST.getlist("perfil-menus")
            user = User.objects.create_user(username=request.POST.get("user-username",""),email=request.POST.get("user-email",""),password=request.POST.get("user-password",""))
            user.first_name = request.POST.get("user-first_name","")
            user.last_name = request.POST.get("user-last_name","")
            user.is_active = request.POST.get("user-is_active","True")
            user.save()
            perfil = Perfil()
            perfil.usuario = user
            perfil.telefono = request.POST.get("perfil-telefono","")
            perfil.departamento = Departamento.objects.get(pk=request.POST.get("perfil-departamento",""))           
            perfil.save()
            men = Menu.objects.filter(pk__in=menus)
            for m in men:
                perfil.menus.add(m)
            form = UsuarioForm(prefix='user')
            form2 = PerfilForm(prefix='perfil')
    else:
        form = UsuarioForm(prefix='user')
        form2 = PerfilForm(prefix='perfil')
    return render(request,'nuevousuario.html',locals())

在这个方法中,我只用简单的

渲染表单
<form id="form" method="post" action=''>{% csrf_token %}
                <table>
                {{form}}
                {{form2}}
                </table>
                <p><input type="submit" value="Registrar"/></p>
            </form>

我想用一些数据填充输入值以编辑用户,但不仅是用户,我需要编辑“Perfil”值。

注意:“菜单”字段在HTML中显示为&lt;选择多个&gt;

对不起西班牙语代码,我在拉丁公司工作。

2 个答案:

答案 0 :(得分:1)

我仍然不确定你要问的是什么,但让我们清理一下。

首先,您需要利用UserCreationForm中的内置django.contrib.auth.forms。其次,从不 永远 直接使用表单帖子中的数据来水合模型对象,因为这完全绕过了由表格课程。第三,可以大大简化视图。我假设您正在使用Django 1.7:

# forms.py

from django import forms

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User

from .models import Perfil

class UsarioForm(UserCreationForm):
    class Meta:
        model = User
        exclude = ()

class PerfilForm(forms.ModelForm):
    class Meta:
        model = Perfil
        exclude = ('usario',)


# views.py

from django.shortcuts import render

from .forms import UsarioForm, PerfilForm

def nuevo_usario(request):
    usario_form = UsarioForm(request.POST or None)
    perfil_form = PerfilForm(request.POST or None)

    if request.method == 'POST':
        if usario_form.is_valid() and perfil_form.is_valid():
            usario = usario_form.save()
            perfil = perfil_form.save(commit=False)
            perfil.usario = usario
            perfil.save()
            perfil.save_m2m()

    return render(request, 'nuevousario.html',
        {'usario_form': usario_form, 'perfil_form': perfil_form})

让ModelForm类执行他们的设计 - 从清理的数据创建对象。您不必在视图中手动完成所有这些工作。您的模板代码也需要一些帮助:

# nuevousario.html

<form action="." method="post" enctype="application/x-www-form-urlencoded">
    <table>
        <tfoot>
            <tr>
                <td>
                    {% csrf_token %}
                    <button type="submit">Registrar</button>
                </td>
            </tr>
        </tfoot>
        <tbody>
            {{ usario_form.as_table }}
            {{ perfil_form.as_table }}
        </tbody>
    </table>
</form>

您确定要为此表单使用表格吗?它真的是表格数据吗?在语义上看起来不太正确。您可以考虑使用有序列表:<ol>

希望能帮到你。

答案 1 :(得分:0)

以@Brandon的评论为例,我改变了我的代码。

我添加了两个网址,一个用于空表单,另一个用于获取用户数据

#urls.py

url(r'^usuarios/$','main.views.usuarios',name='usuarios'),
url(r'^usuarios/(\d+)$','main.views.usuarios',name='editar_usuario'),

只有一个可以处理两个URL的视图,我查找user_id,如果没有,则显示空表单,否则我获取用户和配置文件数据,并且instance我放了数据进入输入字段

#views.py

def usuarios(request,id_usuario=None):
    usuarios = User.objects.all()
    #Pide información de un usuario - Ask for user Info
    if id_usuario is not None: 
        usr = User.objects.get(pk=id_usuario)
        prf = Perfil.objects.get(usuario=usr)
        usuario_form = UsuarioForm(instance=usr)
        perfil_form = PerfilForm(instance=prf)
    #El formulario está vacío para nuevo usuario -Empty User Form
    else:
        usuario_form = UsuarioForm(request.POST or None)
        perfil_form = PerfilForm(request.POST or None)
    #Botón Registrar - Register Button pressed
    if request.method == 'POST':
        #Si está editando se obtiene la instancia del que quiere guardar - If edit, then gets the instance to save
        if id_usuario is not None:
            usuario_form = UsuarioForm(request.POST, instance=usr)
            perfil_form = PerfilForm(request.POST, instance=prf)
        #Finalmente guarda - Finally Saves the form
        if usuario_form.is_valid() and perfil_form.is_valid():
            usuario = usuario_form.save()
            perfil = perfil_form.save(commit=False)
            perfil.usuario = usuario
            perfil.save()
            HttpResponseRedirect('/usuarios/')
    return render(request,'usuarios.html',locals())

最后,我在表单中添加了一些bootstrap / crispy,使其看起来更好。

#Template usuarios.html
{% block content %}
<div class="row">
    <div class="col-md-4">
        <h3>Usuarios Registrados</h3>
        <ul>
        {% for usuario in usuarios %}
            <li><a class="usuario_link" href="/usuarios/{{usuario.pk}}">{{ usuario.username }} - {{ usuario.first_name }}</a></li>
        {% empty %}
            <li>No hay usuarios.</li>
        {% endfor %}
        </ul>
    </div>
    <div class="col-md-5">
        <fieldset>
            <form id="form" method="post" action=''>{% csrf_token %}
                {{usuario_form|crispy}}
                {{perfil_form|crispy}}
                <p><input class="btn btn-default" type="submit" value="Registrar"/></p>
            </form>
        </fieldset>
    </div>
    <div class="col-md-2 col-md-offset-1">
        <a href="/usuarionuevo/"><input class="btn btn-default" type="button" value="Nuevo Usuario" /></a>    
    </div>
</div>
{% endblock %}

我希望它对某人有所帮助,我是python和django的新手,所以,再次感谢@Brandon的精彩辅导。

如果有人有更好的答案,请告诉我。