I implemented this functionality with using FBV, but when I'm trying to use CBV, Objects were created with empty user field.
views.py
class BlockCreate(CreateView):
model = TrainingBlock
template_name = 'training_room/create_block.html'
form_class = BlockForm
success_url = reverse_lazy('gym')
def set_user(self, form):
form.instance.user = self.request.user
return super(BlockCreate, self).set_user(form)
models.py
class TrainingBlock(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
duration = models.IntegerField(default=10)
if_ended = models.BooleanField(default=False)
def __str__(self):
return self.name
forms.py
class BlockForm(forms.ModelForm):
class Meta:
model = TrainingBlock
fields = '__all__'
exclude = ['user']
CodePudding user response:
There is no .set_user
method in a CreateView
, hence the logic will never get invoked. You use .form_valid(…)
[Django-doc] instead:
from django.contrib.auth.mixins import LoginRequiredMixin
class BlockCreate(LoginRequiredMixin, CreateView):
model = TrainingBlock
template_name = 'training_room/create_block.html'
form_class = BlockForm
success_url = reverse_lazy('gym')
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
Note: You can limit views to a view to authenticated users with the
@login_required
decorator [Django-doc].
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
Note: Since PEP-3135 [pep], you don't need to call
super(…)
with parameters if the first parameter is the class in which you define the method, and the second is the first parameter (usuallyself
) of the function.