Reputation: 761
I'm trying to add an instance to the Books model, which is added using the inheriting form of ModelForm, the Books instance is added, but I'm not able to relate the user field to the User model.
forms.py
from django import forms
from .models import Books
class BooksCreationForm(forms.ModelForm):
class Meta:
model = Books
fields = ('title',
'language', 'status', 'short_desc',
)
models.py
User = settings.AUTH_USER_MODEL
class Books(models.Model):
STATUS_CHOICES = (
('Reading', 'Reading'),
('Finished', 'finished'),
)
user = models.ForeignKey(User, on_delete=models.SET_NULL, related_name='books',null=True)
title = models.CharField(max_length=120)
short_desc = models.TextField(max_length=1000)
slug = AutoSlugField(populate_from='title', overwrite=True)
language = models.CharField(max_length=20, blank=True)
status = models.CharField(max_length=35, choices=STATUS_CHOICES)
views.py
class AddBooksView(View):
# ....
def post(self, request, *args, **kwargs):
template = self.template
form = self.form(request.POST)
# ?? user = User.objects.get(request.user)
user = User.objects.get(username=request.user.username)
if form.is_valid():
form.save(commit=False)
form.user = user
form.save()
print("book post sucess")
return redirect('main:books')
context = {'form': self.form()}
return render(request, template, context)
But when i add in the shell, works:
>>> u = User.objects.get(username='marcos')
>>> u.email
'[email protected]'
>>> bk = Books.objects.create(title='stackoverflow', language='Python', status='reading', short_desc='desc...')
>>> bk.title
'stackoverflow'
>>> bk.user = u
>>> bk.user.username
'marcos'
>>> bk.save()
>>> for v in Books.objects.filter(user=u):
... print(v.title, v.user.username)
...
stackoverflow marcos
several instances that i try save through ModelForm have user = None:
>>> for v in Books.objects.all():
... print(v.user, v.title)
...
None Pyhon2
None dfdsffffff
None fgdfdfd
None fgdfgfg
marcos stackoverflow # that i add before using shell
I also try removing user in the view and using this in the form:
class BooksCreationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
return super(BooksCreationForm, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
kwargs['commit'] = False
instance = super(BooksCreationForm, self).save(*args, **kwargs)
if self.request:
instance.user = self.request.user
instance.save()
return instance
class Meta:
model = Books
fields = ('title',
'language', 'status', 'short_desc',
)
Upvotes: 1
Views: 71
Reputation: 14360
You have to get the new book instance and assign the user to it, not to the form try:
if form.is_valid():
book = form.save(commit=False)
book.user = user
book.save()
return redirect('main:books')
See examples here Form's save method.
Upvotes: 1
Reputation: 1810
Try using CreateView for your AddbooksView as:
class AddBooksView(CreateView):
# ...
#specify your form
def form_valid(self, form):
form.save(commit=False)
form.user = self.request.user
form.save()
print("book post sucess")
return redirect('main:books')
#...
For reference follow this link: http://melardev.com/eng/blog/2017/11/04/createview-django-4-examples/
Upvotes: 0