• Расширение модели User в Django - AUTH_PROFILE_MODULE

    @marazmiki
    Укротитель питонов
    Не советую нормально запускать то что написали: слишком уж много идеологических ошибок.

    Во-первых, Вы не проверяете пользовательский ввод. Два примера: у Вас в модели Team уникальный индекс на поле name. Если пользователь введёт в POST-форме имя команды, которое уже существует, вывалится ошибка базы данных. Аналогичная ситуация с User.

    Во-вторых, Вы Вы создаёте User, но не создаёте UserProfile. Сам он создаваться не будет, следовательно, вызов user.get_profile() (у Вас, кстати, скобочек не было, отсюда и AttributeError).

    В-третьих, Вы пытались в поле внешнего ключа, которое должно принимать объект модели, пытаетесь передать целочисленное значение. Надо было так:
    user.get_profile().team = team


    Как правильно? Используйте ModelForm. Они возьмут на себя рутинную работу по грамотной валидации данных и будут возвращать сконструированные инстансы моделей.

    Хотя конкретно в этом случае ModelForm не очень подойдёт, потому что данные сохраняются в несколько разных моделей. В таких случаях приходится использовать Form и чуть-чуть програмировать, а именно описывать нестандартную логику валидациитам, где это требуется (метод clean_something описывает пользовательскую валидацию поля something, подробности в разделе Form and field validation документации).

    Код формы (forms.py) будет примерно таким (писалось экспромтом и не тестировалось, не надо бездумно копипастить):
    # -*- coding: utf-8 -*-
    from django import forms
    from django.contrib.auth.models import User
    
    class RegisterForm(forms.Form):
        username = forms.CharField()
        email    = forms.EmailField()
        password = forms.CharField()
        teamname = forms.CharField()
    
        def clean_username(self):
            """
            Проверим уникальность юзернейма
            """
            username = self.cleaned_data.get('username')
    
            if User.objects.filter(username=username).count() > 0:
                raise forms.ValidationError, 'User %s is already exists' % username
            return username
    
        def clean_team(self):
            """
            Проверим уникальность имени команды
            """
            name = self.cleaned_data.get('teamname')
    
            if Team.objects.filter(name=name).count() > 0:
                raise forms.ValidationError, 'Team %s is already exists' % name
            return name
        
        def clean(self):
            """
            Подготовка чистых данных для вставки в модель
            """
            data = super(RegisterForm, self).clean()
    
            data['user'] = User.objects.create_user(
                username = data['username'],
                password = data['password'],
                email    = data['email'],
            )
            data['team'] = Team.objects.create(
                name = data['teamname'],
            )
    
            return data


    А кусок с самой регистрацией в views.py будет выглядеть примерно так:
    form = RegisterForm(request.POST or None)
    if form.is_valid():
        data = form.cleaned_data
        profile, created = UserProfile.objects.get_or_create(
            user = data['user'], # user - модель, а не строка
            team = data['team'], # team тоже модель
        )
    


    При желании можно инкапсулировать создание UserProfile в классе формы. Это даже правильнее, но в данном случае непринципиально :)

    Если я где-то ошибся или непонятно — спрашивайте и добро пожаловать в клуб :)
    Ответ написан
    1 комментарий
  • Как обрабатывать исключение в цикле?

    @maxfox
    print([a / b for a, b in zip(number,number1) if b != 0])
    Ответ написан
    Комментировать