ManyToManyField的重复条目

时间:2017-08-23 13:18:07

标签: django

我有一个表单来创建新用户。

创建用户后,它会为其创建一个Profil。

在Profil的模型中,我有一个ManyToManyField。

到现在为止,一切正常。

然后我自动登录用户并插入ManyToManyField。

问题出在我的数据库中,我在ManyToManyField中没有注册条目。并且没有发生任何错误,因此很难知道什么是问题

这是我的模特:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    birthdate = models.DateField(null=True, blank=True)
    avatar = models.FileField(upload_to=user_directory_path, validators=[validate_file_extension], blank=True, null=True)
    sex = models.CharField(max_length=12, null=False)
    favori = models.ManyToManyField(Games, verbose_name="Jeu")

我的全部观点:

def view_register(request):
    step = '1'

    if step == '1':
        minimum_form = MinimumRegisterForm()

    if request.method == 'POST':

        if '2' in request.POST:
            step = '2'
            minimum_form = MinimumRegisterForm(request.POST)

            if minimum_form.is_valid():
                identifiant = minimum_form.cleaned_data['identifiant']
                email = minimum_form.cleaned_data['email']
                password = minimum_form.cleaned_data['password']
                confirm_password = minimum_form.cleaned_data['confirm_password']
                sex = minimum_form.cleaned_data['sex']

                #Verification

                character_allowed = ['!', '_', '-', '$']

                for letter in identifiant:
                    if not (letter.isalpha() or letter.isdigit() or letter in character_allowed):
                        step = '1'
                        messages.add_message(request, messages.INFO, 'Votre identifiant ne peut contenir que les charactères spcéciaux suivants : %s.' %(character_allowed))

                if len(identifiant) > 15 :
                    step = '1'
                    messages.add_message(request, messages.INFO, 'Votre identifiant doit être inférieur à 16 charactères alphanumériques, actuellement il y en a %s.' %(len(identifiant)))

                if User.objects.filter(email=email).exists():
                    step = '1'
                    messages.add_message(request, messages.INFO, 'Cette adresse e-mail est déjà utilisé.')

                if User.objects.filter(username=identifiant).exists():
                    step = '1'
                    messages.add_message(request, messages.INFO, 'Cet identifiant n\'est pas disponible.')              

                if password == confirm_password:
                    strengh = password[0].isalpha()

                    if all(c.isalpha() == strengh for c in password):
                        step = '1'
                        messages.add_message(request, messages.INFO, 'Le mot de passe doit contenir au moins 8 charactères alphanumériques.')
                else:
                    step = '1'
                    messages.add_message(request, messages.INFO, 'Confirmation du mot de passe invalide.')

                #Fin de la vérification

            favori_form = GamesRegisterForm()

        if '3' in request.POST:
            step = '3'

            identifiant = request.POST['identifiant']
            email = request.POST['email']
            password = request.POST['password']
            confirm_password = request.POST['confirm_password']
            sex = request.POST['sex']

            #Verification

            character_allowed = ['!', '_', '-', '$']

            for letter in identifiant:
                if not (letter.isalpha() or letter.isdigit() or letter in character_allowed):
                    step = '1'
                    messages.add_message(request, messages.INFO, 'Votre identifiant ne peut contenir que les charactères spcéciaux suivants : %s.' %(character_allowed))

            if len(identifiant) > 15 :
                step = '1'
                messages.add_message(request, messages.INFO, 'Votre identifiant doit être inférieur à 16 charactères alphanumériques, actuellement il y en a %s.' %(len(identifiant)))

            if User.objects.filter(email=email).exists():
                step = '1'
                messages.add_message(request, messages.INFO, 'Cette adresse e-mail est déjà utilisé.')

            if User.objects.filter(username=identifiant).exists():
                step = '1'
                messages.add_message(request, messages.INFO, 'Cet identifiant n\'est pas disponible.')              

            if password == confirm_password:
                strengh = password[0].isalpha()

                if all(c.isalpha() == strengh for c in password):
                    step = '1'
                    messages.add_message(request, messages.INFO, 'Le mot de passe doit contenir au moins 8 charactères alphanumériques.')
            else:
                step = '1'
                messages.add_message(request, messages.INFO, 'Confirmation du mot de passe invalide.')

            #Fin de la vérification             

            #Validation du Google Captcha
            recaptcha_response = request.POST.get('g-recaptcha-response')
            url = 'https://www.google.com/recaptcha/api/siteverify'
            values = {
                'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
                'response': recaptcha_response
            }
            data = urllib.parse.urlencode(values).encode()
            req =  urllib.request.Request(url, data=data)
            response = urllib.request.urlopen(req)
            result = json.loads(response.read().decode())

            if result['success']:
                user = User.objects.create_user(identifiant, email, password)
                user.save()

                user_id = user.pk
                Profile.objects.filter(user=user_id).update(sex=sex)

                user = authenticate(username = identifiant, password = password)
                login(request, user)


                favori_form = GamesRegisterForm(request.POST, instance=request.user)

                if favori_form.is_valid():
                    favori_form.save()
                else :
                    step = '1'
                    messages.add_message(request, messages.INFO, 'Problème d\'instance. ')

            else:
                step = '1'
                messages.add_message(request, messages.INFO, 'Un problème est survenu lors de la validation de Google Captcha.')

    return render(request, 'register.html', locals())

forms.py:

class GamesChoiceField(ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        media = settings.MEDIA
        logo = '<img src="%s{url}"/>'.format(url=obj.logo) %(media)
        return mark_safe("{logo} {title}".format(title=obj.title, logo=logo))

class GamesRegisterForm(forms.ModelForm):
    game = Games.objects.all()
    favori = GamesChoiceField(widget=forms.CheckboxSelectMultiple, required=True, queryset=game)

    class Meta:
        model = Profile
        fields = ('favori', )

2 个答案:

答案 0 :(得分:1)

要获得更好的答案需要完整的视图代码,但是对于当前信息,您可以尝试:

instance, _ = Profile.objects.get_or_create(user=user)

favori_form = GamesRegisterForm(request.POST, instance=instance)
if favori_form.is_valid():
    favoris = favori_form.save()

答案 1 :(得分:1)

如果我关注您的观点,我认为.create_user(..)应该放在if favori_form.is_valid():之前为什么? 因为您需要先创建用户,然后再保存favori favori模型中Profile可用的地方。

基本上,流程应该是:

  • 创建新用户
  • 使用当前用户创建配置文件。
  • favori分配给当前个人资料。
if request.method == 'POST':
    identifiant = request.POST['identifiant']
    email = request.POST['email']
    password = request.POST['password']
    confirm_password = request.POST['confirm_password']
    sex = request.POST['sex']

    # Verification
    # your verivication goes here.....

    # create new user
    new_user = User.objects.create_user(identifiant, email, password)
    new_user.save()

    # create new profile
    profile = Profile.objects.create(user=new_user, sex=sex)
    profile.save()

    # instance the `favori` form with current profile.
    favori_form = GamesRegisterForm(request.POST, instance=profile)
    if favori_form.is_valid():
        # do stuff
  

对于 recaptcha ,我建议您使用此django-nocaptcha-recaptcha插件,以便更轻松。