在这种情况下,为什么UserChangeForm模型会创建一个对象而不是更新它?

2024-09-25 08:39:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在使用UserChangeForm来更新用户表单,当我尝试通过请求post发送时,函数确实起作用,但不会更改用户对象,而是像create方法一样保存对象。 那么,在这个时刻,我怎么能改变表单对象呢

views.py

# Edit Your account
@login_required
def edit_profile(request, user_slug=None):
    template_name = 'account/edit_profile.html'
    if request.method == "POST":
        request_user = request.user.userprofile
        user_profile = UserProfile.objects.get(slug=user_slug)
        form = EditForm(request.POST)
        if form.is_valid():
            form.instance.slug = user_slug
            form.save()
            return redirect('account:view_profile', form.instance.slug)
        return render(request, template_name, {'form': form})
    else:
        form = EditForm()
        user_profile = UserProfile.objects.get(slug=user_slug)
        return render(request, template_name, {'form': form})

url.py

urlpatterns = [
    path('view-profile/<slug:user_slug>/', views.view_profile, name='view_profile'),
    # /account/edit-profile/
    path('edit-profile/<slug:user_slug>/', views.edit_profile, name='edit_profile'),
]

编辑表单.html

{% extends 'base.html' %}
{% block title %} Edit Profile {% endblock %}

{% block body %}

    <div class="edit-form">
        <div class="container">
            <div class="my-form">
                <form method="post">
                    {% csrf_token %}
                    {% for field in form %}
                    <div class="form-group">
                        <label for="exampleInputEmail1">{{ field.label_tag }}</label>
                        <p>{{ field }}</p>
                    </div>
                    {% endfor %}
                <button type="submit" class="btn btn-primary btn-lg">Change Password</button>
                </form>
            </div>
        </div>
    </div>

    {% include 'base_footer.html' %}

{% endblock %}

forms.py

# Edit your data except password
class EditForm(UserChangeForm):
    password = None

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

    def edit(self, fields):
        user = super(EditForm, self).save(commit=False)

        if user.commit:
            user.save()
        return user

Tags: namedivformview表单returnrequesthtml
2条回答

Every ModelForm also has a save() method. This method creates and saves a database object from the data bound to the form. A subclass of ModelForm can accept an existing model instance as the keyword argument instance; if this is supplied, save() will update that instance. If it’s not supplied, save() will create a new instance of the specified model

因此,您只需将实例传递给EditForm

# Edit Your account
@login_required
def edit_profile(request, user_slug=None):
    template_name = 'account/edit_profile.html'
    if request.method == "POST":
        request_user = request.user.userprofile
        user_profile = UserProfile.objects.get(slug=user_slug)
        # if instance is supplied, save will update instead of create
        form = EditForm(request.POST, request.FILES, instance=user_profile)
        print(form.errors) # check if any errors
        if form.is_valid():
            # form.instance.slug = user_slug
            form.save()
            return redirect('account:view_profile', form.instance.slug)
        return render(request, template_name, {'form': form})
    else:
        user_profile = UserProfile.objects.get(slug=user_slug)
        # prepopulate the form data with model instance
        form = EditForm(instance=user_profile)
        return render(request, template_name, {'form': form})

注意:如果您也上传图像,请记住也要传递request.FILES

您不需要在模型表单上提供编辑函数,我建议使用基于类的泛型视图,因为它易于使用和扩展。以下是我的建议:

Forms.py

class UpdateUserForm(ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email']

#views.py

from django.views.generic import View
from .forms import UpdateUserForm
from django.contrib import messages
#import your forms and functions including UpdateUserForm

class UserView(View):
    def get(self, *args, **kwargs):
        form = UpdateUserForm(instance=self.request.user)
        context = {'form':form}
        return render(self.request, template, context)

    def post(self, *args, **kwargs):
        form = UpdateUserForm(self.request.POST or None, instance=self.request.user)
        if form.is_valid():
            form.save()
            messages.success(self.request, 'Info updated')
            return redirect('user-profile')
        context = {'form':form}
        messages.error(self.request, 'Please, check the form for errors')
        return render(self.request, template, context)



#function based view
def update_user(request):
    form = UpdateUserForm(instance=request.user)
    if request.method == 'POST':
        form = UpdateUserForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
            return render(...)
    return render(request, template, {'form':form}

这就是我为用户信息更新创建视图的方式,它就像一个符咒

模板文件

{% extends 'base.html' %}
{% block title %} Edit Profile {% endblock %}

{% block body %}

<div class="edit-form">
    <div class="container">
        <div class="my-form">
            <form method="post">
                {% csrf_token %}
                {% for field in form %}

                            <div
                                class="input-group no-border form-control-lg {% if field.errors %} has-danger {% endif %} ">
                                <span class="input-group-prepend">
                                    <div class="input-group-text">
                                        <i class="now-ui-icons users_single-02"></i>
                                    </div>
                                </span>
                                {% render_field field class="form-control" %}
                            </div>

                            {% if field.errors %}
                            {% for error in field.errors %}
                            <div class="text-left text-danger font-weight-bolder">
                                <p>{{ error|escape}}</p>
                            </div>
                            <script>
                            $('.form-control').addClass('form-control-danger')
                            </script>
                            {% endfor %}
                            {% endif %}

                            {% endfor %}
            <button type="submit" class="btn btn-primary btn-lg">Change Password</button>
            </form>
        </div>
    </div>
</div>

{% include 'base_footer.html' %}

{% endblock %}

如果使用引导,则可以使用Javascript添加样式

{% block page_script %}
<script>
var $list = $("form :input[type='text']");
$list.each(function () {
    $(this).addClass("form-control");
});
var $select = $("form select");
$select.each(function () {
    $(this).addClass("custom-select w-90");
});
var $select = $("form textarea");
$select.each(function () {
    $(this).addClass("form-control");
});
var $list = $("form :input[type='number']");
$list.each(function () {
    $(this).addClass("form-control");
});
{% endblock %}

相关问题 更多 >