Вопрос о Django и аутентификации пользователя - PullRequest
1 голос
/ 29 апреля 2011

нубский вопрос Джанго:

Я использую dango.contrib.auth для управления пользователями моего сайта. Но сейчас я разрабатываю «страницу настроек», где пользователь может редактировать свое имя, фамилию и адрес электронной почты. Но на странице настроек я также хочу установить флажок "Рассылка".

Вопросы: 1) Где мне разместить поле новостной рассылки в базе данных? 2) Как я могу создать форму для редактирования этой информации?

Спасибо.

- ОБНОВЛЕНИЕ -

Теперь у меня есть это в models.py:

.
class UserProfile(models.Model):
    user = models.ForeignKey(User, unique = True)
    favourite_color = models.CharField(max_length = 40)

и это в forms.py:

class UserSettingsForm(forms.ModelForm):

    class Meta:
        model = User
        exclude = ('password',)

    def save(self, commit=False):
        user = super(UserSettingsForm,self).save(commit)
        favourite_color = self.cleaned_data.get('favourite_color', '')
        if favourite_color and user.favourite_color is None:
            UserProfile(user=user).save()
        if not slug:
            UserProfile.objects.filter(user=user).delete()

        if not commit:
            user.save()
        return user

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

Ответы [ 5 ]

6 голосов
/ 29 апреля 2011

Вы хотите посмотреть профили пользователей .

РЕДАКТИРОВАТЬ: Что касается форм, что-нибудь мешает вам использовать две формы? Я думаю, что Django игнорирует поля в HTTP-запросе, которые не соответствуют форме, поэтому вы можете передать запрос двум формам. При визуализации шаблона Django не генерирует теги <form> или кнопку отправки, поэтому вы просто помещаете обе формы в один <form>. Нечто подобное на ваш взгляд (изменение примера Django ):

def edit_user_view(request):
    if request.method == 'POST': # If the form has been submitted...
        # Two forms bound to the POST data
        userForm = UserForm(request.POST)
        profileForm = ProfileForm(request.POST)
        if userForm.is_valid() and userForm.is_valid():
            # All validation rules pass
            # Process the data in userForm. and profileForm.cleaned_data
            # ...
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        # Unbound forms
        userForm = UserForm()
        profileForm = ProfileForm()

    return render_to_response('edit_user.html', {
        'userForm': userForm,
        'profileForm': profileForm,
    })

А в шаблоне:

<form action="/contact/" method="post">{% csrf_token %}
{{ userForm.as_p }}
{{ profileForm.as_p }}
<input type="submit" value="Submit" />
</form>

Это действительно только отправная точка, но я не вижу причин, по которым она не может работать.

0 голосов
/ 21 мая 2011

Я не знаю, хороший ли это способ.Но вы не можете создать специальный класс для вашего профиля пользователя (или у вас есть еще одна таблица в базе данных, поэтому поиск пользователей медленнее).

Я пытался сделать следующее :

{ utils.py }

class Utils:

        class ClassContributor: 

            @staticmethod
            def contribute_fields( object_class, *fields ):
                for val in fields:                      
                    field_name = val[ 0 ]
                    field = val[ 1 ]
                    field.contribute_to_class( object_class, field_name )


{ models.py }

    user_contributor = Utils.ClassContributor.contribute_fields(    
        User, 
        ( 'country', models.ForeignKey( Country, null = True ) ),
        ( 'region', models.ForeignKey( Region, null = True ) ),
        ( 'city', models.ForeignKey( City, null = True ) ),
    )

В этом случае у нас есть только одна таблица в базе данных (проблема: добавленные поля не видны в администраторе django).

Я буду искать решение проблемы.

0 голосов
/ 30 апреля 2011

решено :

это в forms.py:

    class UserProfileForm(forms.ModelForm):
        first_name = forms.CharField(label = 'First name', max_length = 40)
        last_name = forms.CharField(label = 'Last name', max_length = 40)
        email = forms.CharField(label = 'Email', max_length = 40)

        def __init__(self, *args, **kw):
            super(UserProfileForm, self).__init__(*args, **kw)
            self.fields['first_name'].initial = self.instance.user.first_name
            self.fields['last_name'].initial = self.instance.user.last_name
            self.fields['email'].initial = self.instance.user.email

        def save(self, *args, **kw):
            profile = super(UserProfileForm, self).save(*args, **kw)
            u = self.instance.user
            u.first_name = self.cleaned_data['first_name']
            u.last_name = self.cleaned_data['last_name']
            u.email = self.cleaned_data['email']
            u.save()
            return profile

        class Meta:
            model = UserProfile
            exclude = ('user', )

и в views.py:

def settings(request):
    user = request.user.get_profile()
    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance = user)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('')

    form = UserProfileForm(instance = user)
    return render(request, "settings.html", {'form': form})
0 голосов
/ 29 апреля 2011

Вы также можете использовать наследование и позволить django управлять сохранением.

class UserProfile(User):
    favourite_color = models.CharField(max_length = 40)

class UserProfileForm(forms.ModelForm):    
    class Meta:
        model = UserProfile
        exclude = ('password',)

Это создаст однозначное поле в UserProfile, указывающее на пользователя. Поля пользователя будут сохранены в модели пользователя, а другие поля - в модели UserProfile.

0 голосов
/ 29 апреля 2011

Создание новой модели со ссылкой на модель пользователя и создание ModelForm на основе пользователя, но с дополнительными полями.

class Subscription(models.Model):
    user = models.OneToOneField(User, null=True, blank=True, related_name='subscription')

class UserSettingsForm(forms.ModelForm):
    subscribed = forms.BooleanField(default=False)

    class Meta:
        model = User
        exclude = ('password',)

    def save(self, commit=False)
        user = super(UserSettingsForm,self).save(commit)
        subscribed = self.cleaned_data.get('subscribed', False)
        if subscribed and user.subscription is None:
            Subscription(user=user).save()
        if not subscribed:
            Subscription.objects.filter(user=user).delete()

        if not commit:
            user.save()
        return user

Вы также захотите передать начальные данные относительно информации о подписке при создании формы:

subscribed = user.subscription is not None
form = UserSettingsForm(instance=user, initial={subscribed=subscribed})

Это должно позаботиться об этом. В данный момент у меня нет личного примера, но это сделано по памяти. Я постараюсь обновить его позже сегодня, если я что-то пропустил.

...