创建用于创建新用户的自定义页面。该页面编辑和删除用户没有问题。当我创建一个用户时,我收到 django.db.utils.IntegrityError: (1062, "Duplicate entry 'johndoe@gmail.com' for key 'accounts_user.email'")。我知道我的代码试图保存该条目两次。根据我的回溯,我认为这与表单中的保存函数与视图中的 form.save() 冲突有关。这是所有代码。我已经用尽了我(有限的)想法。
views.py
@admin_only
def index(request):
user_accounts = User.objects.all()
print(user_accounts)
context = {'accounts': user_accounts}
return render(request, 'accounts/user_accounts.html', context)
@admin_only
def create_account(response):
data = dict()
form = CreateAccountForm()
if response.method == 'POST':
form = CreateAccountForm(response.POST)
if form.is_valid():
form.save()
data['form_is_valid'] = True
user_accounts = User.objects.all().order_by('id')
data['accounts_list'] = render_to_string('accounts/account_list.html', {'accounts': user_accounts})
else:
data['form_is_valid'] = False
context = {'form': form}
data['html_form'] = render_to_string('accounts/create_account.html', context, request=response)
return JsonResponse(data)
forms.py
class UserAdminCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
class Meta:
model = User
fields = (
'email',
'first_name',
'last_name',
)
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class CreateAccountForm(UserAdminCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = [
"first_name",
"last_name",
"email",
"phone",
"mobile_phone",
"sms_messages",
"active",
"staff",
"admin",
"H1A",
"H1B",
"H2A",
"H2B",
"H3A",
"H3B",
"H5A",
"H5B",
"H6A",
"H6B",
"backshop",
"DoD_P8",
"Commercial",
"password1",
"password2",
]
user_accounts.html
{% extends "main/base.html" %}
{% block title %}
Manage User Accounts
{% endblock %}
{% block content %}
{% load crispy_forms_tags %}
<head>
</head>
<div class="container-xl-fluid mx-auto" style="width: 95%">
<div class="row justify-content-md-center mb-2" style="padding-top: 20px">
<div class="col-md-12 mb-4 shadow-lg p-3 bg-white rounded">
<div id="dashboard_parent" class="header mb-2">
<h3 class="header mb-2 text-center">Manage User Accounts</h3>
<!-- Modal -->
<div id="modal-aircraft" class="modal fade" data-backdrop="static" data-keyboard="false" role="dialog">
<div class="modal-dialog modal-lg">
<!-- Modal content-->
<div class="modal-content" style="margin-top: 4vh;"></div>
</div>
</div>
<div id="toolbar">
<button class="btn show-form" data-url="{% url 'create_account' %}" title="Add Account" style="color: Dodgerblue;"><i class="fas fa-plus fa-lg"></i></button>
</div>
<table id="table" class="accounts table table-sm table-bordered w-auto mx-auto"
data-toolbar="#toolbar"
data-toggle="table"
data-search="true"
data-show-export="true"
data-show-print="true"
data-show-multi-sort="true"
data-show-multi-sort-button="true"
data-method="multiSort"
data-export-types="['pdf', 'txt', 'csv', 'xlsx']"
data-buttons-align="left"
data-search-align="left"
data-show-refresh="false"
>
<thead class="accounts_header">
<tr id="header_accounts" class="text-center">
<th></th>
<th data-field="id" data-sortable="true">ID</th>
<th data-field="first_name" data-sortable="true">First Name</th>
<th data-field="last_name" data-sortable="true">Last Name</th>
<th data-field="email" data-sortable="true">email</th>
<th data-field="phone" data-sortable="true">Phone</th>
<th data-field="mobile_phone" data-sortable="true">Mobile Phone</th>
<th data-field="sms_messages" data-sortable="true">SMS</th>
<th data-field="active" data-sortable="true">Active</th>
<th data-field="staff" data-sortable="true">Staff</th>
<th data-field="admin" data-sortable="true">Admin</th>
<th data-field="H1A" data-sortable="true">H1A</th>
<th data-field="H1B" data-sortable="true">H1B</th>
<th data-field="H2A" data-sortable="true">H2A</th>
<th data-field="H2B" data-sortable="true">H2B</th>
<th data-field="H3A" data-sortable="true">H3A</th>
<th data-field="H3B" data-sortable="true">H3B</th>
<th data-field="H5A" data-sortable="true">H5A</th>
<th data-field="H5B" data-sortable="true">H5B</th>
<th data-field="H6A" data-sortable="true">H6A</th>
<th data-field="H6B" data-sortable="true">H6B</th>
<th data-field="backshop" data-sortable="true">Backshop</th>
<th data-field="Commercial" data-sortable="true">Commercial</th>
<th data-field="DoD_P8" data-sortable="true">P-8A</th>
<th></th>
</tr>
</thead>
<tbody id="account-table-body" class="searchable">
{% include "accounts/account_list.html" %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock content%}
create_account.html
{% load crispy_forms_tags %}
<form method="POST" enctype="multipart/form-data" data-url="{% url 'create_account' %}" id="create-form" class="create-form">
{% csrf_token %}
<div class="modal-header">
<!--<button type="button" class="close ml-0 pl-0" data-dismiss="modal">×</button>-->
<h4 class="modal-title">Create New Account</h4>
</div>
<div class="modal-body">
<div class="col">
<form method="POST" id="create-account" class="form-group create-form">
{% csrf_token %}
<div class="form-row d-flex justify-content-center">
<div class="form-group col-md-4-mb-0">
{{form.first_name|as_crispy_field}}
</div>
<div class="form-group col-md-4-mb-0">
{{form.last_name|as_crispy_field}}
</div>
<div class="form-group col-md-4-mb-0">
{{form.email|as_crispy_field}}
</div>
</div>
<div class="form-row d-flex justify-content-center">
<div class="form-group col-md-4-mb-0">
{{form.phone|as_crispy_field}}
</div>
<div class="form-group col-md-4-mb-0">
{{form.mobile_phone|as_crispy_field}}
</div>
</div>
<div class="form-row d-flex justify-content-center">
{{form.sms_messages|as_crispy_field}}
</div>
<div class="text-center border-top">
<h5>Account Status</h5>
</div>
<div class="form-row d-flex justify-content-center">
<div class="form-group col-md-6-mb-0" id="active">
{{form.active}}
<label class="form-check-label" for="active">
Active |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="staff">
{{form.staff}}
<label class="form-check-label" for="staff">
Staff |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="admin">
{{form.admin}}
<label class="form-check-label" for="admin">
Admin
</label>
</div>
</div>
<div class="text-center border-top">
<h5>Account Permissions</h5>
</div>
<div class="form-row d-flex justify-content-center">
<div class="form-group col-md-6-mb-0" id="DoD_P8">
{{form.DoD_P8}}
<label class="form-check-label" for="DoD_P8">
DoD_P8 |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="Commercial">
{{form.Commercial}}
<label class="form-check-label" for="Commercial">
Commercial
</label>
</div>
</div>
<div class="text-center border-top">
<h5>Assigned Work Stations</h5>
</div>
<div class="form-row d-flex justify-content-center">
<div class="form-group col-md-6-mb-0" id="H1A">
{{form.H1A}}
<label class="form-check-label" for="H1A">
H1A |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="H2A">
{{form.H2A}}
<label class="form-check-label" for="H2A">
H2A |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="H3A">
{{form.H3A}}
<label class="form-check-label" for="H3A">
H3A |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="H5A">
{{form.H5A}}
<label class="form-check-label" for="H5A">
H5A |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="H6A">
{{form.H6A}}
<label class="form-check-label" for="H6A">
H6A
</label>
</div>
</div>
<div class="form-row d-flex justify-content-center">
<div class="form-group col-md-6-mb-0" id="H1B">
{{form.H1B}}
<label class="form-check-label" for="H1B">
H1B |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="H2B">
{{form.H2B}}
<label class="form-check-label" for="H2B">
H2B |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="H3B">
{{form.H3B}}
<label class="form-check-label" for="H3B">
H3B |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="H5B">
{{form.H5B}}
<label class="form-check-label" for="H5B">
H5B |
</label>
</div>
<div class="form-group col-md-6-mb-0" id="H6B">
{{form.H6B}}
<label class="form-check-label" for="H6B">
H6B
</label>
</div>
</div>
<div class="form-row d-flex justify-content-center">
<div class="form-group col-md-6-mb-0" id="backshop">
{{form.backshop}}
<label class="form-check-label" for="backshop">
Backshop
</label>
</div>
</div>
<div class="form-row d-flex justify-content-center">
<div class="form-group col-md-4-mb-0">
{{form.password1|as_crispy_field}}
</div>
<div class="form-group col-md-4-mb-0">
{{form.password2|as_crispy_field}}
</div>
</div>
{% if request.GET.next %}
<input type="hidden" name="next" value="{{request.GET.next}}">
{% endif %}
<button type="submit" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
</form>
</div>
</div>
<div class="modal-footer">
</div>
</form>
script.js
// create account records
$('.show-form').click(ShowAccountForm);
$('#modal-aircraft').on('submit', '.create-form', SaveAccountForm)
// update account records
$('#account-table-body').on('click', '.show-form-update', ShowAccountForm)
$('#modal-aircraft').on('submit', '.update-form', SaveAccountForm)
// delete account records
$('#account-table-body').on('click', '.show-form-delete', ShowAccountForm)
$('#modal-aircraft').on('submit', '.delete-form', SaveAccountForm)
var SaveAccountForm = function(){
var form = $(this);
$.ajax({
url: form.attr('data-url'),
data: form.serialize(),
type: form.attr('method'),
dataType: 'json',
success: function(data){
if(data.form_is_valid){
$('#account-table-body').html(data.accounts_list);
$('#modal-aircraft').modal('hide');
} else {
$('#modal-aircraft .model-content').html(data.html_form)
}
}
})
return false;
}
var ShowAccountForm = function(){
var btn = $(this);
$.ajax({
url: btn.attr('data-url'),
type: 'get',
dataType: 'json',
beforeSend: function(){
$('#modal-aircraft').modal('show');
},
success: function(data){
$('#modal-aircraft .modal-content').html(data.html_form);
}
});
};
traceback
Internal Server Error: /accounts/create_account/
Traceback (most recent call last):
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\backends\mysql\base.py", line 74, in execute
return self.cursor.execute(query, args)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\MySQLdb\cursors.py", line 209, in execute
res = self._query(query)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\MySQLdb\cursors.py", line 315, in _query
db.query(q)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\MySQLdb\connections.py", line 239, in query
_mysql.connection.query(self, query)
MySQLdb._exceptions.IntegrityError: (1062, "Duplicate entry 'johndoe@gmail.com' for key 'accounts_user.email'")
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\antho\Developer Apps\PyCharmProjects\EGHub\accounts\views.py", line 51, in _inner
return function(request, *args, **kwargs)
File "C:\Users\antho\Developer Apps\PyCharmProjects\EGHub\accounts\views.py", line 85, in create_account
form.save()
File "C:\Users\antho\Developer Apps\PyCharmProjects\EGHub\accounts\forms.py", line 64, in save
user.save()
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\contrib\auth\base_user.py", line 66, in save
super().save(*args, **kwargs)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\base.py", line 745, in save
self.save_base(using=using, force_insert=force_insert,
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\base.py", line 782, in save_base
updated = self._save_table(
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\base.py", line 887, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\base.py", line 924, in _do_insert
return manager._insert(
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\query.py", line 1204, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\sql\compiler.py", line 1392, in execute_sql
cursor.execute(sql, params)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\backends\utils.py", line 100, in execute
return super().execute(sql, params)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\backends\utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\backends\mysql\base.py", line 74, in execute
return self.cursor.execute(query, args)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\MySQLdb\cursors.py", line 209, in execute
res = self._query(query)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\MySQLdb\cursors.py", line 315, in _query
db.query(q)
File "C:\Users\antho\AppData\Local\Programs\Python\Python38\lib\site-packages\MySQLdb\connections.py", line 239, in query
_mysql.connection.query(self, query)
django.db.utils.IntegrityError: (1062, "Duplicate entry 'johndoe@gmail.com' for key 'accounts_user.email'")