1π
I do this by overriding CreateView.get_form_class()
in order to modify the attributes of the relevant field of the form before it is passed to the rest of the view.
The default method, inherited from views.generic.edit.ModelFormMixin
, returns a ModelForm that represents all the editable fields of the model in the base_fields
dictionary. So itβs a good place to make any desired changes and also has access to self.request.user
.
So for the above example, in views.py we might say:
class ContentCreateView(LoginRequiredMixin, CreateView):
model = Content
fields = '__all__'
def get_form_class(self):
modelform = super().get_form_class()
modelform.base_fields['folder'].limit_choices_to = {'user': self.request.user}
return modelform
Read more about ForeignKey.limit_choices_to
in the docs.
Note that field choices are enforced by form validation so this should be quite robust.
0π
The following mixin looks automatically limits the choices for all foreign key fields that point to a model that has a user field:
class LimitForeignKeyChoicesToSameUserMixin:
def get_form_class(self):
this_model_has_user_field = False
choice_limited_fields = []
for field in self.model._meta.get_fields():
if isinstance(field, ForeignKey) or isinstance(field, ManyToManyField):
if field.name == 'user':
this_model_has_user_field = True
elif hasattr(field.related_model, 'user'):
choice_limited_fields.append(field.name)
form_class = super().get_form_class()
if this_model_has_user_field:
for field in choice_limited_fields:
form_class.base_fields[field].limit_choices_to = {'user': self.request.user}
return form_class
And then I use the following base class for all βaddβ views:
class AddViewBase(LoginRequiredMixin, LimitForeignKeyChoicesToSameUserMixin,
CreateView, FormMixin):
slug_url_kwarg = 'id'
slug_field = 'id'
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
And this base class for βeditβ views:
class EditViewBase(LoginRequiredMixin, LimitForeignKeyChoicesToSameUserMixin,
UpdateView):
slug_url_kwarg = 'id'
slug_field = 'id'
- [Answered ]-If / else in Django View
- [Answered ]-How do I create a serializer for one to many (Foreign key) relationship?
- [Answered ]-Django model validation not raising Exception on full_clean()
- [Answered ]-Django β Change timeuntil language without changing application language