IntegrityError at/person/ create / UNIQUE constraint failed: member_person.идентификатор пользователя

моя модель:

class Person(models.Model):
    name = models.CharField(max_length=250)
    slug = AutoSlugField(populate_from='name')
    birth_date = models.DateField(null=True, blank=True)
    blood_group = models.CharField(max_length=5)
    present_address = models.CharField(max_length=250, blank=True)
    permanent_address = models.CharField(max_length=250, blank=True)
    user = models.OneToOneField(
               settings.AUTH_USER_MODEL,
               related_name='member_persons')

мой взгляд:

@require_authenticated_permission(
'member.add_person')
class PersonCreate(CreateView):
    template_name = 'member/person_form.html'
    model = Person
    success_url = '/person/'
    form_class = MemberForm

    def get_form(self, form_class=None):
        form = super().get_form(form_class)
        form.request = self.request
        return form

моя форма:

class MemberForm(ModelForm):

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

    def clean_user(self):
        user = self.cleaned_data['user']
        if Person.objects.filter(user=user).exists():
             raise forms.ValidationError("You already submitted data")
        return user

    def save(self, commit=True):
         person = super().save(commit=False)
         if not person.pk:
             person.user = get_user(self.request)
         if commit:
             person.save()
             self.save_m2m()
         return person

Это сработало хорошо для первого экземпляра человека, но когда я попытался отправить форму члена снова с другими данными, это дает следующую ошибку целостности:

Traceback:

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py" in execute
  337.         return Database.Cursor.execute(self, query, params)

The above exception (UNIQUE constraint failed: member_person.user_id) was the direct cause of the following exception:

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
  39.             response = get_response(request)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapper
  67.             return bound_func(*args, **kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/utils/decorators.py" in bound_func
  63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapper
  67.             return bound_func(*args, **kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/utils/decorators.py" in bound_func
  63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/views/generic/base.py" in dispatch
  88.         return handler(request, *args, **kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/views/generic/edit.py" in post
  217.         return super(BaseCreateView, self).post(request, *args, **kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/views/generic/edit.py" in post
  183.             return self.form_valid(form)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/views/generic/edit.py" in form_valid
  162.         self.object = form.save()

File "/home/ohid/test_venv/persontest/member/forms.py" in save
  37.             person.save()

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/models/base.py" in save
  796.                        force_update=force_update, update_fields=update_fields)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/models/base.py" in save_base
  824.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/models/base.py" in _save_table
  908.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/models/base.py" in _do_insert
  947.                                using=using, raw=raw)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/models/manager.py" in manager_method
  85.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/models/query.py" in _insert
  1045.         return query.get_compiler(using=using).execute_sql(return_id)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1054.                 cursor.execute(sql, params)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  79.             return super(CursorDebugWrapper, self).execute(sql, params)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/utils.py" in __exit__
  94.                 six.reraise(dj_exc_type, dj_exc_value, traceback)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/utils/six.py" in reraise
  685.             raise value.with_traceback(tb)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/home/ohid/test_venv/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py" in execute
  337.         return Database.Cursor.execute(self, query, params)

Exception Type: IntegrityError at /person/create/
Exception Value: UNIQUE constraint failed: member_person.user_id

Я знаю, что это причины поля моей модели:

user = models.OneToOneField(
               settings.AUTH_USER_MODEL,
               related_name='member_persons')

Я хочу показать сообщения «Вы уже отправили данные» в форме создания члена, а не получать эту ошибку. Мог бы кто-нибудь подсказать, как я мог бы этого достичь.

Редактировать:

шаблон формы:

{% extends parent_template|default:"member/base_member.html" %}

{% load crispy_forms_tags %}
{% load i18n %}

{% block body %}


    <div class="container-fluid">

        <div class="row">
            <div class="col-sm-12 col-md-7">
                <div class="panel panel-default">
                    <div class="panel-body">

                        <form class="form-horizontal" action="" method="post" enctype="multipart/form-data">
                            {% csrf_token %}

                            {{ form|crispy }}


                            <div class="form-group">
                                <div class="col-sm-offset-6 col-sm-6">
                                    <button type="submit" class="btn btn-success">Submit</button>
                                </div>
                            </div>

                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

{% endblock %}

шаблон списка лиц:

{% extends parent_template|default:"member/base_member.html" %}
{% load crispy_forms_tags %}

{% block body %}


    {% if perms.member.add_person %}

        <div class="page-header">
            <div class="row">
            <div class="col-sm-3 ">
                   <a class="btn btn-primary" href="{% url 'member:person-list' %}">View All Member</a>

            </div>

            <a class="btn btn-primary pull-right" href="{% url 'member:person-create' %}"><i class="icon-plus icon-white"></i> Add New Member</a>
                </div>
        </div>
    {% endif %}

    <div class="container-fluid">
        <div class="row ">

        <div style="overflow-x:auto;">

        <div class="col-sm-8 col-md-9">
            <h3>Members List</h3>

        {% if persons %}
            <table>

            <tr>
                <th>sl.</th>
                <th>Name and Position</th>
                <th>Photo</th>
                <th>Organisation & Address</th>
                <th>Contact</th>
            </tr>



            {% for person in persons %}
            <tr>
                <td>{{forloop.counter}}.</td>
                <td><a href="{{person.get_absolute_url}}">
               {{person.name}}
                </a></td>

                <td>{{person.birth_date}}</td>


                <td>
                {{person.blood_group}}<br>
                {{person.present_address}}
                </td>



                {% if user.pk == person.user.pk or user.is_superuser  %}
                <td>
                    <a href="{{person.get_update_url}}">
                <button type="button" class="btn btn-primary btn-sm">
                    <span class="glyphicon glyphicon-pencil">Update</span>
                </button></a>
                </td>

                {% endif %}

                <td><a href="{{person.get_delete_url}}">
                <button type="submit" class="btn btn-default btn-sm">
                    <span class="glyphicon glyphicon-trash">Delete</span>
                </button>
                </a></td>

            </tr>

            {% endfor %}
            </table>
        {% else %}
            <p>No person in the list.</p>
        {% endif %}
        </div>
            </div>
    </div>
    </div>
{% endblock %}

1 ответ

  1. Поскольку вы исключили userиз полей, он не запускает ваш clean_userметод. Вместо этого можно использовать cleanметод формы. И ошибка поля

    class MemberForm(ModelForm):
        class Meta:
            model = Person
            exclude = ('user', )
    
        def clean(self):
            user = get_user(self.request)
            if Person.objects.filter(user=user).exists():
                self.add_error('name', "You already submitted data")
            return self.cleaned_data
    
        def save(self, commit=True):
            ...