models.py is :
class Todo(models.Model):
user=models.ForeignKey(User,on_delete=models.CASCADE,null=True,blank=True)
title=models.CharField(max_length=200)
desc=models.TextField(null=True,blank=True)
complete=models.BooleanField(default=False)
created=models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Meta:
ordering = ['created']
views.py is:
class TaskCreate(generic.CreateView):
model = Todo
fields = '__all__'
template_name = 'create.html'
success_url = reverse_lazy('home')
create.html is:
<body>
<a href="{% url 'home' %}">go back</a>
{{ form.as_p }}
<form method="post">
{% csrf_token %}
<input type="submit" value="submit">
</form>
</body>
Whenever I submit data from create.html form it doesn't save it to the database and throws this field is required on 'user' field. How do I resolve this?
CodePudding user response:
You probably want to exclude the user
field, since it is determined by the logged in user, so:
from django.conf import settings
class Todo(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, editable=False
)
# …
def __str__(self):
return self.title
class Meta:
ordering = ['created']
Then we inject the logged in user in the instance of the form:
from django.contrib.auth.mixins import LoginRequiredMixin
class TaskCreateView(LoginRequiredMixin, generic.CreateView):
model = Todo
fields = '__all__'
template_name = 'create.html'
success_url = reverse_lazy('home')
def form_valid(self, form):
form.instance.user = request.user
return super().form_valid(form)
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: You can limit views to a class-based view to authenticated users with the
LoginRequiredMixin
mixin [Django-doc].
Note: In Django, class-based views (CBV) often have a
…View
suffix, to avoid a clash with the model names. Therefore you might consider renaming the view class toTaskCreateView
, instead of.TaskCreate