I’m trying to make some form using ModelForm
and CreateView
.
So, I tried this.
model.py
from django.conf import settings
from django.db import models
# Create your models here.
class Schedule(models.Model):
srl = models.BigAutoField(
primary_key=True,
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.DO_NOTHING,
)
branch = models.ForeignKey(
"branches.Branch",
on_delete=models.DO_NOTHING,
)
start_datetime = models.DateTimeField()
end_datetime = models.DateTimeField()
class Meta:
ordering = [
"branch",
"start_datetime",
]
forms.py
from django import forms
from django.forms import ModelChoiceField, ModelForm
from branches.models import Branch
from schedules.models import Schedule
from users.models import User
class ScheduleForm(ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
super(ScheduleForm, self).__init__(*args, **kwargs)
if self.user.superuser:
self.fields["branch"] = ModelChoiceField(
queryset=Branch.objects.all(),
required=True,
label="Branch",
widget=forms.Select(
attrs={
"class": "form-select",
}
),
)
self.fields["user"] = ModelChoiceField(
queryset=User.objects.all(),
required=True,
label="User",
widget=forms.TextInput(
attrs={
"class": "form-control",
"list": "user-list",
}
),
)
else:
self.fields["branch"] = ModelChoiceField(
queryset=Branch.objects.filter(branch=self.user.branch),
required=True,
label="Branch",
widget=forms.Select(
attrs={
"class": "form-select",
}
),
)
self.fields["user"] = ModelChoiceField(
queryset=User.objects.filter(branch=self.user.branch),
required=True,
label="User",
widget=forms.TextInput(
attrs={
"class": "form-control",
"list": "user-list",
}
),
)
class Meta:
model = Schedule
fields = (
"start_datetime",
"end_datetime",
)
widgets = {
"start_datetime": forms.DateTimeInput(
attrs={
"type": "datetime-local",
"class": "form-control",
},
),
"end_datetime": forms.DateTimeInput(
attrs={
"type": "datetime-local",
"class": "form-control",
},
),
}
views.py
class ScheduleCreateView(CreateView):
model = Schedule
form_class = ScheduleForm
success_url = reverse_lazy("schedules:list")
def get_form_kwargs(self):
kwargs = super(ScheduleCreateView, self).get_form_kwargs()
kwargs.update({"user": self.request.user})
return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["page_title"] = "Create Schedule"
if self.request.user.superuser:
context["user_list"] = User.objects.all()
else:
context["user_list"] = User.objects.filter(branch=self.request.user.branch)
return context
But I got this.
So refer to the answer of my previous question about NOT NULL Constraint, I changed views.py
into this
class ScheduleCreateView(CreateView):
model = Schedule
form_class = ScheduleForm
success_url = reverse_lazy("schedules:list")
def form_valid(self, form):
if form.is_valid():
form.instance.branch_id = form.cleaned_data["branch"]
form.instance.user_id = form.cleaned_data["user"]
form.instance.start_datetime = form.cleaned_data["start_datetime"]
form.instance.end_datetime = form.cleaned_data["end_datetime"]
return super(ScheduleCreateView, self).form_valid(form)
def get_form_kwargs(self):
kwargs = super(ScheduleCreateView, self).get_form_kwargs()
kwargs.update({"user": self.request.user})
return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["page_title"] = "Create Schedule"
if self.request.user.superuser:
context["user_list"] = User.objects.all()
else:
context["user_list"] = User.objects.filter(branch=self.request.user.branch)
return context
Now, I got this.
So my question is these.
- How can I solve this?
- Why NOT NULL Constraint error occured even I used same field name in the model and form?
- Why ForeignKey column’s name always have suffix ‘_id’ and how to avoid this?