Как создать пользовательскую UserChangeForm, которая не позволяет редактировать определенные поля? - PullRequest
4 голосов
/ 02 апреля 2011

Это мой второй пост на SO, а также мой второй пост на Django - будьте осторожны.

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

views.py

from django.shortcuts import render_to_response, get_object_or_404
from django.core import urlresolvers
from django.http import HttpResponseRedirect
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import UserChangeForm

@login_required 
def settings( request, template_name = 'accounts/settings.html' ):
    """
    Processes requests for the settings page, where users
    can edit their profiles.
    """
    page_title = 'Account Settings'
    if request.method == 'POST':
        postdata = request.POST.copy()
        form = UserChangeForm( postdata )
        if form.is_valid():
            form.save()
    else:
        form = UserChangeForm()
    title = 'Settings'
    return render_to_response( template_name, locals(), context_instance = RequestContext( request) )

Как будто это не было 'Достаточно плохо, эта форма не позволяет вносить какие-либо изменения, ссылаясь на «Пользователь с таким именем уже существует» в качестве ошибки.Это сбивает меня с толку - я пытаюсь сохранить UserChangeForm, поэтому разве он уже не был бы задан?

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

forms.py

class CustomUserChangeForm( UserChangeForm ):
    def __init__( self, *args, **kwargs ):
        super( CustomUserChangeForm, self ).__init__( *args, **kwargs )
        if self.instance and self.instance.pk:
            # Since the pk is set this is not a new instance
            self.fields['username'] = self.instance.username
            self.fields['username'].widgets.attrs['readonly'] = True

К сожалению, это не сработало.Я как бы в растерянности относительно того, что делать, поэтому любая помощь будет принята с благодарностью.Ниже приведены мои urls.py и шаблон:

urls.py

urlpatterns = patterns('appname.accounts.views',

    url(r'^settings/$', 'settings', { 
            'template_name': 'accounts/settings.html' 
        }, 'settings'
    ),
)

template

{% extends "accounts/base.html" %}

{% block main %}
    <h1>Welcome, {{ request.user.pk }}{{ request.user.username }} to accounts.templates.accounts.settings.html.</h1>
    <h2>Here you can update your user settings. You can change your password <a href="{% url change_password %}">here</a>.</h2>
    <form action="." method="post" accept-charset="utf-8">
        {% csrf_token %}
        {{ form.as_p }}
        <p><input type="submit" value="Update &rarr;"></p>
    </form>
{% endblock %}

Заранее благодарен за любую помощь!

Ответы [ 5 ]

8 голосов
/ 02 апреля 2011

Первое: чтобы ограничить поля в форме, следуйте документации . Существует два варианта фильтрации полей: fields и exclude.

.

Второе: вы всегда создаете нового пользователя. Инициализируйте форму с экземпляром User, не только вы сможете сохранить форму, но у вас будет набор исходных данных.

Ваш код просмотра должен выглядеть следующим образом:

# in the POST:
form = UserChangeForm(request.POST, instance=request.user)

# otherwise
form = UserChangeForm(instance=request.user)

и удалить присвоение значения из form.py.

4 голосов
/ 24 сентября 2013

Это необходимо обновить: вы не можете исключить поля в UserChangeForm ()

Слишком плохо.

2 голосов
/ 02 апреля 2011

Три вещи.Прежде всего, вы должны установить self.fields ['username'] в поле формы, например, формы.Во-вторых, по вашему мнению, вы используете UserChangeForm вместо CustomUserChangeForm.И в-третьих, http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#using-a-subset-of-fields-on-the-form (правильная ссылка, а не ссылка на чей-то жесткий диск ...

1 голос
/ 10 января 2017

У меня получилось добавить класс формы (в forms.py), переопределяющий UserChangeForm:

from django.contrib.auth.forms import UserChangeForm    

class UserChangeForm(UserChangeForm):
"""Overriding visible fields."""
    class Meta:
        model = User
        fields = ('username', 'password', 'email', 'first_name', 'last_name',)

Наконец, импортируйте эту версию в views.py вместо contrib.auth.forms

1 голос
/ 02 апреля 2011

Похоже, вы не внимательно прочитали документацию.

Позвольте мне помочь вам с этим, посмотрите , используя подмножество полей в форме .

По сути, вам просто нужно добавить exclude = ('fieldname',) к мета-модели вашей модели.

...