Alxe
Alxe

Reputation: 391

Set a form field to the current logged user id

I have a class Task with the following implementation:

class Task(models.Model):
    author = models.ForeignKey(Author, unique=False)
    name = models.CharField(max_length=255)
    completed = models.BooleanField(default=False)
    deadline = models.DateTimeField(null=True, blank=True)
    pub_date = models.DateTimeField(auto_now_add=True, editable=False)
    edit_date = models.DateTimeField(auto_now_add=True, auto_now=True, editable=False)
    tag = models.ManyToManyField(Tag, related_name='tags', null=True, blank=True, default=None)
    # group = models.ForeignKey(Group, blank=True, default=None)

    def __str__(self):
        return u'%s' % (self.name)

    def toggle_complete(self):
        self.completed = not self.completed

    def is_past_deadline(self):
        return timezone.now() > self.deadline

And I am trying to do a simple form that creates a new Task with a Title. But, as you can see, the author attribute can not be null (and don't want to, of course).

Author is implemented as follows:

class Author(models.Model):
    user = models.OneToOneField(User, primary_key=True)
    name = models.CharField(max_length=30)

    def __str__(self):
        return u'%s' % (self.user)

I tried and tried to hide the author field and, overriding methods like get_form_kwargs, form_valid, get_form to set it to the current logged user, but I always fail. Simply, the id is neither sent as post data (as seein in the debug trace), nor fetched from the view itself.

My best result has been showing the author field, creating the user correctly, but getting a "success_url" not found, even with the model having a get_absolute_url method declared.

The view I am working with is implemented like:

class HomeView(CreateView, MultipleObjectMixin):
    # common
    model = models.Task
    template_name = 'home.html'

    #form
    form_class = TaskForm

    # list
    object_list = model.objects.all()
    context_object_name = 'tasks'
    paginate_by = 40

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated():
            return HttpResponseRedirect(reverse('taskr:index'))
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get_form_kwargs(self):
        kwargs = super(HomeView, self).get_form_kwargs()
        kwargs['initial']['author_id'] = self.request.user.id
        return kwargs

    def form_valid(self, form):
        task = form.save(commit=False)
        task.user = models.Author.objects.get(user=self.request.user)  # use your own profile here
        task.save()
        return HttpResponseRedirect(self.get_success_url())

For the record, the MultipleObjectMixing part of the view works flawlessly.

I am desperate, is there any good resource for Django forms, one like http://ccbv.co.uk/? Thanks.

Upvotes: 2

Views: 860

Answers (1)

Alxe
Alxe

Reputation: 391

After a good night sleep, while cleaning up, I tried fixing the form_valid in the CreateView descendant and I got it right.

The trick is in

task.user = models.Author.objects.get(user=self.request.user)

and it failed to me because of desperate copy-pasting. The problem was that my Task model has no user attribute, but an author. So

task.author = models.Author.objects.get(user=self.request.user)

fixes it all.

Sorry for the stupid question.

Upvotes: 1

Related Questions