Valera
Valera

Reputation: 49

Foreign key POST in Django

I have some problems with my app . I need to make task with relations to user.

Here is my code:

bug

 ValueError at /
Cannot assign "(<SimpleLazyObject: <function AuthenticationMiddleware.process_request.<locals>.<lambda> at 0x04C54E38>>,)": "Task.usertask" must be a "UserMembership" instance.

models.py

class UserMembership(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True,blank=True)
    image=models.FileField(upload_to='photos/%Y/%m/%d/',null=True,blank=True)


class Task(models.Model):
    title=models.CharField(max_length=200)
    date = models.DateTimeField(default=datetime.now,blank=True)
    is_published=models.BooleanField(default=True)
    usertask=models.ForeignKey(UserMembership, on_delete=models.PROTECT, null=True, blank=True)

views.py

if request.method == 'POST':
    usertask = request.user,
    title = request.POST['title']
    task = Task(usertask=usertask,title=title)
    task.save()

task = Task.objects.order_by('-date').filter(is_published=True, usertask=request.user.id)

context={
    'task':task,
}
return render(request,'index.html',context)

html form

<form action="" method="POST">
{% csrf_token %}

    <input name="title" type="text" class="form-control" id="usr">

<button type="submit" class="btn btn-primary">add</button>

Upvotes: 1

Views: 1302

Answers (3)

kamilyrb
kamilyrb

Reputation: 2627

Your task model's usertask field related with UserMembership model as ForeignKey.So you must give a UserMembership object for create Task object. You gave request.user as usertask but request.user is'nt a UserMembership object.You must find UserMembership object before. You can use following code:

user_member_ship = UserMemberShip.objects.get(user=request.user)
Task.objects.create(title=title,usertask=user_member_ship)

Upvotes: 3

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476729

As the error says your usertask field of your Task model refers to a UserMembership, not a User object.

You can use .get_or_create() [Django-doc] to retrieve, or create such object if it does not yet exists. For example:

def myview(request):
    if request.method == 'POST':
        usertask, __ = UserMembership.objects.get_or_create(
            user=request.user
        )
        title = request.POST['title']
        task = Task.objects.create(usertask=usertask, title=title)
    task = Task.objects.order_by('-date').filter(
        is_published=True,
        usertask__user=request.user
    )
    context={
        'task':task,
    }
    return render(request,'index.html',context)

You should filter on the usertask__user=request.user, since again, a usertask will retrieve a UserMembership object, not a User object.

I strongly advice to work with forms [Django-doc] and not try to process the request.POST querydictionary yourself. It is for example possible that the POST request does not contain any value for title, which can raise errors. A form will handle that more elegantly.

Upvotes: 1

Daniel
Daniel

Reputation: 3527

A few things:

1) in your views function you are doing this: usertask = request.user. Note that request.user will return a User object.

2) You then try to create a Task object by doing this task = Task(usertask=usertask,title=title) but here you have set usertask to a User object when you really need a UserMembership object

You can try rewriting your view function like so:

def MyViewFunction(request):

    # unpack request:
    user = request.user
    title = request.POST['title']

    # create new UserMembership object:
    user_membership = UserMembership.objects.create(user=user)
    user_membership.save()

    # create new Task object:
    task = Task.objects.create(usetask=user_membership, title=title)
    task.save()

    # continue code here...

Upvotes: 1

Related Questions