Django User Update Form and View

谁说胖子不能爱 提交于 2020-01-03 01:37:13

问题


I am very early on in my Django/Python development journey, most things I have been able to slowly figure out after a few hours/days of head scratching and trial/error. I now have the commonly asked question that I cannot get working correctly:

How Do I Create a User Profile Update View/Form?

I have hacked on several solutions from Stack Overflow, and just cannot figure out what I am doing wrong thus far. Here is the initial version of my poor attempt using Django 1.9:

#forms.py
class profileForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email']

#views.py
@login_required
def profile(request):
    if request.method == 'POST':
        form = profileForm(data=request.POST, instance=request.user)
        update = form.save(commit=False)
        update.user = request.user
        update.save()
    else:
        form = profileForm(instance=request.user)

    return render(request, 'profile.html', {'form': form})

#urls.py
urlpatterns = [
    url(r'^dashboard/$', views.dashboard, name='dashboard'),
    url(r'^dashboard/profile$', views.profile, name='profile'),
]

#profile.html
<form action="." method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Update Profile</button>
</form>

So the current behaviour of my update user profile view is to not update any of the specified fields in the form on POST, but the page does load to a different URL. For example the URL for the profile update form is /dashboard/profile which redirects to /dashboard on form submission. If I manually add email/first_name/last_name in the Django admin, it is displayed correctly in my form... I just cannot get it to save updated data.

I did have a version of the above code that was giving me username errors also, which I am guessing might have been close to a solution? Eventually I would like to use the email address as the username, but I would like to figure that out for myself once I have an ultra-simple working profile update form.

I apologise in advance for the silly question, I have Googled around and attempted other solutions but I either cannot get the same initial errors or cannot get a working version as detailed.

Thanks all and have a great day/night!

EDIT:

I have also tried this solution How to update User object without creating new one?, which also has the same behaviour: not update any of the specified fields in the form on POST, but the page does load to a different URL... which confuses me more, maybe the issue is with my urls.py instead?


回答1:


There's nothing specific to users here. You have two problems: the first is because of your urls. Your profile view does not end in a slash, so the form's action of "." sends it to the parent, "/dashboard", and it does not go through the processing code at all.

url(r'/dashboard/profile/$'...)

Secondly, the model will not be updated because you have not called the form's valdation method.

if request.method == 'POST':
    form = profileForm(data=request.POST, instance=request.user)
    if form.is_valid():
        form.save()
        return redirect('somewhere')

Note there is no reason to use the commit=False stuff here; the instance is already the user.




回答2:


I tried with abstract user and it is working perfectly. First of all I created an app named dashboard. Then overwrite default User model.

Now Update dashboard app - models.py, urls.py, forms.py and views.py

In models.py

class User(AbstractUser):    
    middle_name = models.CharField(max_length=50, blank=True, null=True)
    sdl_service_code = models.CharField(choices=SDL_CHOICES, max_length=5)
    account = models.CharField(choices=ACCOUNT_CHOICES, max_length=5)

I made This new User model (in dashboard app) django default User model by updating setting file as below

In settings.py

AUTH_USER_MODEL = 'dashboard.User'

In urls.py

urlpatterns = [
    path('users', ListUserView.as_view(), name='users'),
    path('users/add/', CreateUserView.as_view(), name='users-add'),
    path('users/<int:pk>/', UpdateUserView.as_view(), name='users-edit'),
    )
]

In forms.py

class UserForm(forms.ModelForm):            
        middle_name = forms.CharField(required=False, max_length=50)
        password = forms.CharField(widget=forms.PasswordInput())
        about_company = form.CharField(required=False, max_length=50)

        def __init__(self, *args, **kwargs):
            super(UserForm, self).__init__(*args, **kwargs)
            for field in iter(self.fields):
                self.fields[field].widget.attrs.update({
                    'class': 'form-control',
                    'placeholder': '{}'.format(field).replace("_", ' ').capitalize(),

                })

            self.fields['email'].widget.attrs['placeholder'] = 'abc@xyz.com'
            self.fields['email'].required = True
            self.fields['first_name'].required = True
            self.fields['last_name'].required = True
            self.fields['password'].required = True

            if self.instance.pk:
                self.fields['username'].required = False
                self.fields['username'].widget.attrs['readonly'] = True
                self.fields['email'].required = False
                self.fields['email'].widget.attrs['readonly'] = True
                self.fields['password'].widget.attrs['readonly'] = True
                self.fields['password'].required = False

        def save(self, *args, **kwargs):
            self.date_joined = date.today()
            super(UserForm, self).save(*args, **kwargs)
            return self

        class Meta:
            model = User
            fields = '__all__'
            exclude = ('date_joined',)

In views.py

from dashboard.models import User
from django.views.generic import ListView, DetailView, CreateView, UpdateView
from dashboard.forms import UserForm

class CreateUserView(CreateView):
    model = User
    template_name = 'dashboard/user_add.html'
    form_class = UserForm

    def get_success_url(self):
        return '/users'

class UpdateUserView(UpdateView):
    model = User
    form_class = UserForm
    template_name = 'dashboard/user_add.html'
    success_url = '/users'

class ListUserView(ListView):
    model = User
    template_name = 'dashboard/user_list.html'


来源:https://stackoverflow.com/questions/37453821/django-user-update-form-and-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!