УНИКАЛЬНОЕ ограничение не удалось в форме отправки - PullRequest
0 голосов
/ 20 апреля 2020

Я пытаюсь опубликовать форму для создания пользователя. но всякий раз, когда я пытаюсь сохранить данные формы, это всегда дает мне ошибку «УНИКАЛЬНОЕ ограничение», даже если я передаю новый номер мобильного телефона, который не существует в базе данных.

ОШИБКА IS: Сбой ограничения УНИКАЛЬНОЕ : core_user.mobile_no

models.py

Класс менеджера:

class UserManager(BaseUserManager):
    def create_user(self, username, password=None, **extra_fields):
        """Creates and saves a new user"""
        if not password:
            raise ValueError("User must have a password")
        if not username:
            raise ValueError("User must have an username")
        user = self.model(username=username, **extra_fields)
        user.set_password(password)
        user.save(using=self.db)
        return user

    def create_staff_user(self, username, password=None, **kwargs):
        user = self.create_user(username, password, is_staff=True, **kwargs)
        return user

    def create_super_user(self, username, password=None):
        user = self.create_user(self, username=username, password=password, is_staff=True, is_super_user=True)
        return user

Класс модели :

class User(AbstractBaseUser):
    user_types = (
        ("staff", "Staff"),
        ("super_user", "Super User"),
    )

    first_name = models.CharField(max_length=100)
    middle_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    username = models.CharField(max_length=100, unique=True)
    email = models.EmailField()
    mobile_no = models.CharField(max_length=10, unique=True)
    is_active = models.BooleanField(default=True)  # can login
    is_staff = models.BooleanField(default=False)  # staff user
    is_super_user = models.BooleanField(default=False)  # super user
    created_date = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'username'
    objects = UserManager()

    # USERNAME_FIELD and password are required by default
    REQUIRED_FIELDS = []  # e.g full_name

    def __str__(self):
        return self.username

Views.py

class UserCreationView(CreateView):
    template_name = "form.html"
    form_class = UserCreationForm
    success_url = "/"

    def form_valid(self, form):
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']
        first_name = form.cleaned_data['first_name']
        middle_name = form.cleaned_data['middle_name']
        last_name = form.cleaned_data['last_name']
        mobile_no = form.cleaned_data['mobile_no']
        email = form.cleaned_data['email']

        user_type = form.cleaned_data['user_type']

        user_data = {
            "first_name": first_name,
            "middle_name": middle_name,
            "last_name": last_name,
            "mobile_no": mobile_no,
            "email": email
        }

        if user_type == 'super-user':
            user = User.objects.create_super_user(username, password, **user_data)
        else:
            user = User.objects.create_staff_user(username, password, **user_data)

        form.instance.user = user
        form.instance.is_active = True
        form.save()
        return super().form_valid(form)

Вопросы: -

  1. Насколько я попытался отладить, это может быть причиной того, что функции create_staff_user и create_super_user уже создали строку в базе данных, и теперь form.save() также пытается снова вставить строку. (не уверен)

  2. мне нужно сделать form.save(), так как я обнаружил, что super().form_valid(form) также имеет встроенную функцию сохранения формы?

Ответы [ 2 ]

0 голосов
/ 20 апреля 2020

Ну, что касается вашего первого вопроса, это может быть проблемой. Я предполагаю, что до того, как вы создали пользовательскую модель пользователя, вы выполняете миграции и помещаете их в базу данных. Таким образом, в этой части Django также создает свою собственную модель пользователя со всеми доступными столбцами и атрибутами. Я бы посоветовал УДАЛИТЬ вашу таблицу «Пользователи» и снова запустить makemigrations и migrate.

Что касается вашего второго вопроса, то лучшие рекомендации и советы, которые я мог бы дать вам first добавить условие if, чтобы проверить, верны ли данные формы, и затем сохранить форму и опубликовать данные. Хотя мой совет на самом деле не относится к вашему вопросу, суть в том, чтобы всегда проверять данные формы, а после их извлечения сохранять форму (публиковать данные).

В документации он говорит, что класс FormView в случае успеха перенаправит пользователя, а в случае ошибки снова отобразит форму. Тем не менее, CreateView будет только отображать ошибки и сохранять объект, он не будет перенаправлять ни на что. Хотя с CreateView вы можете автоматически сохранять форму и ее данные, она не будет перенаправлять пользователя. Я предлагаю вам использовать класс FormView, который покажет наличие ошибок и перенаправит пользователя в случае успеха, но будьте осторожны и сохраните данные формы в конце функции POST .

Надеюсь, это поможет! Пожалуйста, дайте мне знать, если я могу вам чем-то помочь.

0 голосов
/ 20 апреля 2020

По вашему мнению, вы должны вызывать save только один раз, но вы вызываете его дважды

form.save() # this line saves it to the database
super().form_valid(form) # and this line does that too

, поэтому после вызова form.save () верните ответ. обновите, ваш код на

class UserCreationView(CreateView):
    template_name = "form.html"
    form_class = UserCreationForm
    success_url = "/"

    def form_valid(self, form):
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']
        first_name = form.cleaned_data['first_name']
        middle_name = form.cleaned_data['middle_name']
        last_name = form.cleaned_data['last_name']
        mobile_no = form.cleaned_data['mobile_no']
        email = form.cleaned_data['email']

        user_type = form.cleaned_data['user_type']

        user_data = {
            "first_name": first_name,
            "middle_name": middle_name,
            "last_name": last_name,
            "mobile_no": mobile_no,
            "email": email
        }

        if user_type == 'super-user':
            user = User.objects.create_super_user(username, password, **user_data)
        else:
            user = User.objects.create_staff_user(username, password, **user_data)

        form.instance.user = user
        form.instance.is_active = True
        form.save()
        return HttpResponseRedirect(self.get_success_url())

номер мобильного телефона должен быть уникальным для каждого пользователя

class UserForm(forms.ModelForm):

    class Meta:
        model = User
        exclude = ('is_staff', 'is_superuser',)

    def clean_mobile_no(self):
        mobile_number = self.cleaned_data.get('mobile_no')
        user = User.objects.filter(mobile_no=mobile_number)
        if user:
            raise forms.ValidationError(
                    "mobile no is taken"
                )
        return mobile_number
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...