1
votes

I am trying to update an object named User with the properties username and fullname; my model is below.

class User(models.Model):
"""docstring for User"""

fullname = models.TextField()
username = models.TextField()
password = models.TextField()
createdDate = models.DateTimeField(default=timezone.now)
publishedDate = models.DateTimeField(blank=True, null=True)

def publish(self):
    self.publishedDate = timezone.now
    self.save()

def __str__(self):
    return str("\npk= " + self.pk + " | fullname= " + self.fullname + " | username= " + self.username + "\n")

I have created an edit page and am able to get the values from that page in my view through request.POST["fullname"] and request.POST["username"].

My question is how do I update the entire object without having to specify a specific property in update or without getting the object and setting my new values and saving the object; my view is below.

def editUserByID(request, userID):
    if (request.method == "POST"):
        if (request.POST["userID"] != '' and request.POST["fullname"] != '' and request.POST["username"] != ''):
            user1 = User(
                pk=request.POST["userID"],
                fullname=request.POST["fullname"],
                username=request.POST["username"]
            )

        print(user1)

        # this only updates 1 property, so for multiple properties I would have to write multiple statements
        User.objects.filter(pk=user1.pk).update(fullname=user1.fullname) 

        # is this possible? send the entire object and have it update the DB
        User.objects.filter(pk=user1.pk).update(user1)  

        # this is how I was able to save it, but have to get the existing object again, assign the new values and then save
        updateUser = User.objects.get(pk=user1.pk)
        updateUser.fullname=user1.fullname
        updateUser.username=user1.username
        updateUser.save()

else:
    user2 = User.objects.get(pk=userID)
    return render (request, 'helloworld/editUser.html', {'user': user2})
return redirect('listUsers')

PS: I have been working with Java and .NET until now but am completely new to Python/Django so any help would be highly appreciated.

2
A very big reason to use Django is: that it brings an existing Authentication/Authorization framework which is the base for anything with users including login and anything else. You would use Django because you don't want to implement that form scratch. See docs.djangoproject.com/en/2.1/topics/auth/defaultRisadinha
I am using User as an example, but what if it was car or boat or something like that, is it possible to update the entire object (multiple properties) in one line of code? Thank you for the doc btw, will definitely check it out.Pranav S
"but have to get the existing object again" - you don't need to "get it again". Just store it in a variable, change its fields, and save it whenever you are ready.Risadinha

2 Answers

2
votes

This is mostly the wrong approach. For a start, there is no need to create user1; if you wanted to update an existing object, you should just set the values directly there.

But the way to do this in Django is to use a ModelForm. That has many advantages, especially in that it will validate your input, checking that all required fields have been supplied and that they are of the right type. You can pass your existing user as the instance argument when instantiating the form, then when you save it that instance will be updated.

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = '__all__'

...

def editUserByID(request, userID):
    obj = User.objects.get(userID)
    if request.method == 'POST':
        form = UserForm(request.POST, instance=obj)
        if form.is_valid():
           form.save() # updates the existing object
           return redirect('home')
    else:
        form = UserForm(instance=obj)  #  prepopulates the form with values from the instance
    return render(request, 'mytemplate.html', {'form': form})

Also, I second Risadinha's point that you should not be creating your own User model; use Django's built-in auth framework.

0
votes

You can do it in one line like this:

User.objects.filter(pk=user1.pk).update(fullname=user1.fullname, 
username=user1.username) 

The other way to update models is to use forms like this:

# You can get user based on your logic
user = request.user
# 'EditUserForm' is the custom form, read more about django model forms if you already have not, https://docs.djangoproject.com/en/2.1/topics/forms/modelforms/#the-save-method
user_form = EditUserForm(request.POST, instance=user)
if user_form.is_valid():
    user_form.save()
else:
    user2 = User.objects.get(pk=userID)
    return render (request, 'helloworld/editUser.html', {'user': user2})

return redirect('listUsers')