В моем коде проблема с проверкой уникальности ввода двух полей.
Я определил модель с помощью unique_together
для проверки уникальности записей полей для каждого пользователя, но он принимает дублированную запись, добавленную этим пользователем.
model.py
from django.db import models
from django.contrib.auth.models import User
class UserItem(models.Model):
definer = models.ForeignKey(User, on_delete=models.CASCADE)
item_name = models.CharField(max_length=50)
.
.
class Meta:
unique_together = ("definer", "item_name")
views.py
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views.generic.edit import CreateView, UpdateView, DeleteView
class RecordCreateView(LoginRequiredMixin, CreateView):
model = UserItem
template_name = 'item_new.html'
#excluding "definer" field and inserting its value by form_valid
fields = ['item_name', . . .]
def form_valid(self, form):
form.instance.definer = self.request.user
return super().form_valid(form)
Я ожидаю предупреждения и не позволяю пользователям добавлять новую запись с тем же "item_name", добавленным ранее, но этопринимает их (без предупреждения).
Когда я заменяю «определитель» другими полями, он работает нормально и предупреждает о дублировании записей.Кроме того, когда записи добавляются администратором, это работает, и появляется ожидаемое предупреждение.
Я полагаю, эта проблема заключается в том, что аутентифицированный пользователь вставляется как «определитель» с помощью «def form_valid» после «unique_together =»("определитель", "имя_элемента") "выполнил свою роль.С другой стороны, проверка уникальности выполняется, когда «определитель» пуст.
Что я должен сделать, чтобы решить эту проблему?
Редактировать: Добавление полной модели
```` Full Model in model.py
class UserItem(models.Model):
item_type = models.CharField(max_length=12, verbose_name='Item type')
item_name = models.CharField(max_length=50)
bound = models.CharField(null=True, blank=True, default=None, max_length=4, verbose_name='Bound')
price = models.FloatField(default=0)
maximum_use = models.FloatField(default=0, verbose_name='Maximum use (%)’)
matterial = models.FloatField(null=True, blank=True, default=None, verbose_name='matterial (%)')
energy = models.FloatField(null=True, blank=True, default=None, verbose_name='energy (kcal/k)')
definer = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return "{}, name: {}, definer: {}".format(self.item_type, self.item_name, self.definer,)
def get_absolute_url(self):
return reverse('profile')
class Meta:
unique_together = ("definer", "item_name")
````
```` views.py after @Pedro suggestion to edit
from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin
class RecordCreateView(LoginRequiredMixin, CreateView):
model = UserItem
template_name = 'item_new.html'
fields = ['item_name', 'matterial', 'energy',]
def get_success_url(self):
return reverse('profile')
def form_valid(self, form):
user_item = form.save(commit=False)
user_item.definer = self.request.user
user_item.item_type = 'required'
user_item.bound = 'min'
try:
user_item.save()
except IntegrityError:
form.add_error('item_name', 'Item name is repeated')
return self.form_invalid(form)
return HttpResponseRedirect(self.get_success_url())
````