marcos souza
marcos souza

Reputation: 761

I can not save an object related to the User object

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

Answers (2)

Raydel Miranda
Raydel Miranda

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

Sanip
Sanip

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

Related Questions