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