Контекст:
- с использованием Django 3.0.4.
У меня есть две модели
-
UserProfil
произвольная пользовательская модель, автоматически создаваемая путем регистрации UserList
более или менее простого списка списков
Каждый зарегистрированный пользователь может создать новую запись UserList
в моей модели давая UserList.name
в форме. Если я введу UserList.name
и UserList.profile
в форму, мой шаблон сгенерирует входные данные, и я смогу ввести любое значение. пока это работает.
Но очевидно, что пользователям не следует разрешать выбирать отношение UserList.profile
в шаблоне, потому что в этом случае они могут создать новую запись в списке, относящуюся к другим пользователям. поэтому мне нужно установить значение для текущего пользователя.
Мой подход к сохранению этого отношения заключался в том, что вы видите в SingleListForm.save
моих форм. К сожалению, ничего не сохраняется при вводе значения для * 1029. * в моем шаблоне ввода. Отображается только my form_invalid
сообщение: "Ошибка, что-то пошло не так" .
Кроме того, я также попытался удалить поле profiler
из fields:
в моем SingleListForm
и попытался сохранить. но потом я получаю сообщение
The above exception (NOT NULL constraint failed: profil_userlist.profiler_id) was the direct cause of the following exception:
Вопрос
Как установить по умолчанию или добавить внешний ключ в ModelForm?
models.py
class UserProfil(models.Model):
# --- head
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
# --- relation
user_con = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
# -- link
userlink = models.UUIDField(unique=True, default=uuid4, editable=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# --- body
userinfo = models.TextField(null=True, blank=True, help_text="about you")
#---receiver: if new AUTH.user -> UserProfil create UserProfil entry
@receiver(post_save, sender=settings.AUTH_USER_MODEL, dispatch_uid="new_profil")
def create_new_profil(sender, instance, created, **kwargs):
if created:
UserProfil.objects.create(user_con=instance)
class UserList(models.Model):
# --- head
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
uvlink = models.UUIDField(unique=True, default=uuid4, editable=False)
created_at = models.DateTimeField(default=now, editable=False)
updated_at = models.DateTimeField(auto_now=True)
# --- relation
profiler = models.ForeignKey('UserProfil', on_delete=models.CASCADE)
# -- body
name = models.CharField(max_length=50, blank=False, unique=True, help_text="List Name")
listname_slug = models.SlugField(blank=True)
# -- # Sluggenerator
def save(self, *args, **kwargs):
if not self.listname_slug:
# Newly created object, so set slug
self.listname_slug = slugify(self.name)
super(UserList, self).save(*args, **kwargs)
# -- # END
# def get_absolute_url(self):
# return reverse("store:mylist", kwargs={"listname_slug": self.listname_slug})
def __str__(self):
return "{}".format(self.name[:60])
views.py
class SingleListCreateView(CreateView):
template_name ="store/list/single_list_create.html"
form_class = SingleListForm
success_url = reverse_lazy('store:single_list_create_confirmed')
queryset = UserList.objects.all()
def form_invalid(self, form):
msg = "Error something went wrong"
return self.render_to_response(self.get_context_data(form=form, message=msg))
forms.py
class SingleListForm(ModelForm):
class Meta:
model = UserList
fields = [
'name',
'profiler',
]
labels = {
'name':'List Name'
}
def __init__(self, *args, **kwargs):
super(SingleListForm, self).__init__(*args, **kwargs)
self.fields['name'].help_text
def save(self, commit=True):
# --- get the form data, before saving all
formData = super().save(commit)
# --- get relation of current user
setUserProfil = self.request.user.userprofil.id
# alternative
# setUserProfil = self.request.user.userprofil
# -- set relation
formData.profiler_set.add(setUserProfil)
# alternative
# formData.profiler.add(setUserProfil)
return formData
Решение 1
относится к @ Yellowduck спасибо!
forms.py
class SingleListForm(ModelForm):
class Meta:
model = UserList
fields = [
'name',
]
labels = {
'name':'List Name'
}
def __init__(self, *args, **kwargs):
super(SingleListForm, self).__init__(*args, **kwargs)
self.fields['name'].help_text
views.py
class SingleListCreateView(CreateView):
template_name ="store/list/single_list_create.html"
form_class = SingleListForm
success_url = reverse_lazy('store:single_list_create_confirmed')
queryset = UserList.objects.all()
def form_valid(self, form):
profiler = self.request.user.userprofil
form.instance.profiler = profiler
return super().form_valid(form)
Решение 2
Я также нашел решение, установив ìnitial
в форму и hidden_input
в шаблоне
forms.py
class SingleListForm(ModelForm):
class Meta:
model = UserList
fields = [
'name',
'profiler',
]
labels = {
'name':'List Name'
}
widgets = {
'profiler': forms.HiddenInput()
}
def __init__(self, *args, **kwargs):
super(SingleListForm, self).__init__(*args, **kwargs)
self.fields['name'].help_text
просмотров .py
class SingleListCreateView(CreateView):
template_name ="store/list/single_list_create.html"
form_class = SingleListForm
success_url = reverse_lazy('store:single_list_create_confirmed')
queryset = UserList.objects.all()
def get_initial(self, *args, **kwargs):
initial = super(SingleListCreateView, self).get_initial(**kwargs)
initial['profiler'] = self.request.user.userprofil
initial['name'] = "hello"
return initial