Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

get or create avec un champs unique et un formulaire composé

0 votes

J'ai un formulaire qui se compose de deux autres formulaires liés entre eux par une foreign key.
Le premier est vient du modèle MyUser et le second est vient du modèle Coach.

J'aimerais que lors de la création d'un utilisateur (MyUser + Coach) si MyUser n'existe pas alors l'objet est crée et relié à un object Player crée et si il existe déjà, seulement outrepasser l'erreur dans les formulaires me spécifiant qu'il existe déjà.

J'ai essaye de passer outre via la méthode clean_email(self) dans mon formulaire, de changer la méthode save de mon formulaire mais je n'y arrive pas.

class MyUserForm(forms.ModelForm):
class Meta:
    model = MyUser
    fields = ['first_name', 'last_name', 'email', 'profil_picture', 'street_number', 'street', 'zip_code', 'city', 'phone_number', 'birthday']

def save(self):
    data = self.cleaned_data
    try:
        user = MyUser.objects.get(email=data.get('email'))
        print ('User already exist')
        return user
    except MyUser.DoesNotExist:
        print ('User does not exist')
        user = self.save(commit=False)

        salt = os.urandom(2).hex()

        username = str(user.last_name + user.first_name + salt)
        user.username = username
        return user.save()




class CoachCreateForm(forms.ModelForm):
    class Meta:
        model = Coach
        fields = ['grade', 'first_position', 'second_position',]



class CoachCreateMultiForm(MultiModelForm):
form_classes = {
        'user': MyUserForm,
        'coach': CoachCreateForm,
        }

class CoachCreateView(WithSectionMixin, CreateView):
"""Create a coach
"""

form_class = CoachCreateMultiForm
template_name = "staffManagement/coach_create.html"

def get_context_data(self, **kwargs):
    context = super(CoachCreateView, self).get_context_data(**kwargs)

    context['form'].forms['coach'].fields['first_position'].queryset = PlayerPosition.objects.filter(
        section=self.get_section())
    context['form'].forms['coach'].fields['second_position'].queryset = PlayerPosition.objects.filter(
        section=self.get_section())
    context['form'].forms['coach'].fields['grade'].queryset = CoachPosition.objects.filter(
        section=self.get_section())

    return context

def form_valid(self, form):
    # Check if the user exsit
    user = form['user'].save()

    coach = form['coach'].save(commit=False)
    coach.member = user
    coach.section = self.get_section()
    coach.save()

    return HttpResponseRedirect(self.get_success_url())

def get_success_url(self):
    return reverse_lazy('playerAndCoachInSection', kwargs={'team': self.get_team(), 'section': self.get_section()})


class MyUser(AbstractBaseUser, PermissionsMixin):

username = models.CharField('username', max_length=60, blank=True)
first_name = models.CharField('first name', max_length=30)
last_name = models.CharField('last name', max_length=30)
email = models.EmailField('email address', unique=True, error_messages={
        'unique': "A user with that username already exists.",},)
is_staff = models.BooleanField(
    'staff status',
    default=False,
    help_text='Designates whether the user can log into this admin site.',
)
is_active = models.BooleanField(
    'active',
    default=True,
    help_text=
        'Designates whether this user should be treated as active. '
        'Unselect this instead of deleting accounts.'
    ,
)
date_joined = models.DateTimeField('date joined', default=timezone.now)

objects = MyUserManager()

USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']

class Meta:
    verbose_name = 'user'
    verbose_name_plural = 'users'
    ordering = ['first_name', 'last_name']

def clean(self):
    super(MyUser, self).clean()
    self.email = self.__class__.objects.normalize_email(self.email)
demandé 14-Nov-2016 par Echel8n (246 points)
edité 14-Nov-2016 par Echel8n

tu cites get_or_create donc j'imagine que tu connais https://docs.djangoproject.com/fr/1.10/ref/models/querysets/#get-or-create

et donc le code ici est equivalent à cette fonction, mais je ne comprends pas username qui n'est pas dans le parmi les field du form MyUserForm. Est-ce une propriété du model MyUser ?

L'username est crée lors de la sauvegarde de l'utilisateur en combinant le prénom, le nom et une valeur aléatoire.

Le champs qui me permet de retrouver un utilisateur et de savoir qu'il est déjà rentré est l'adresse email.

Mon problème est que lorsque que j'essaye de remplir ce formulaire et de "l'envoyer", j'ai l'erreur qui me dit que cet utilisateur existe déjà. C'est cette erreur qui fait que la méthode save n'est pas appelée je pense.
Cela vient du fait que le champs email est à unique=True je pense mais j'aimerais le contourner en faisant en sorte que si l'adresse email est déjà utilisée il valide quand même le formulaire et fasse un get MyUser au lieu d'en crée 1 et de le linker à un nouvel object PLayer.

Votre réponse

Preview

Votre nom à afficher ( en option ):
Vie privée: . Votre adresse de messagerie ne sera utilisée que pour l'envoi de ces notifications .
Vérification anti -spam:
Pour éviter cette vérification à l'avenir, Connectez vous ou inscrivez vous.
...