Django: Modify model field value when form is submitted - python

I have a model field for each use that keeps track of their score on my website. Every time a user does some I want to add or subtract from their score.
In this particular case, I would like to change the users score when they publish a post on my site. I am able to access the user's score, but not modify it. Here is what I have so far:
def createPost(request):
user = UserProfile.objects.get(user=request.user)
current_score = user.user_score
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
...
user.user_score = current_score - 1
...
else:
form = PostForm()
return render(request,'feed/userpost_form.html',{'form':form})
I am not getting any errors and publishing the post works fine, just not modifying the user's score. Also, I am using Django 1.11

you were missing user.save()
btw another approach could be:
from django.db.models import F
UserProfile.objects.filter(user=request.user).update(user_score=F('user_score')+1)
important feature of above approach in mentioned context is:
Another useful
benefit of F() is that having the database - rather than Python -
update a field’s value avoids a race condition.
https://docs.djangoproject.com/en/1.8/ref/models/expressions/#avoiding-race-conditions-using-f

Related

Django Edit Form Secure Way

I have edit form (modelform) and for that form I created a url something like /contacts/edit//
My view is method base view and I am passing the contact_id from my template to the view as parameter.
Then that's what I am doing:
def edit_contact(request, contact_id):
is_user_authenticated(request.user.is_authenticated)
contact_person = get_object_or_404(domain.Contact.contacts, pk=contact_id)
if request.method == 'POST':
form = forms.ContactPersonForm(request.POST, instance=contact_person)
if form.is_valid():
form.save()
return HttpResponseRedirect('/contacts/')
However that url can be reached by any user with just giving ID and basically you can edit any person you want.
I could do one more query to DB in order to find if a person is the right person to edit contact information but is that right way to do that? What's best practice for my situation?

Django Row Level Locking For Model Forms

I am using Python 3.5, Django 1.8 and PostgreSql 9.4.
So I have one edit method where in get request I am rendering form and when user submit form it will get updated. Hers's the code
def edit_case(request, case_id):
case = get_object_or_404(Case, pk=case_id)
if request.method == 'POST':
data = request.POST.copy()
form = CaseEditForm(data, instance=case)
if form.is_valid():
res = form.save()
return HttpResponseRedirect(reverse("case_list"))
else:
form = CaseEditForm(instance=case)
variables = RequestContext(request, {
"form": form,
})
return render_to_response(
'sample/edit_case.html',
variables,
)
Now I want to add row level locking on it like if one user is updating something at the same time other will not be able update anything unless previous transaction succeeded Or if someone have any other better suggestions rather then using Pessimistic Locking.
I know about select_for_update but don't have any idea how it will get implemented in case of form.save()
Any help would be really appreciated
After so much research I have figured out the solution. So now while getting queryset against id I am using "select_for_update", something like this
with transaction.atomic():
case = get_object_or_404(Case.objects.select_for_update(), pk=case_id)
form = CaseEditForm(data, instance=case)
if form.is_valid():
res = form.save()
return HttpResponseRedirect(reverse("case_list"))
So as you can see now I am fetching the query set object under the transaction and if any exception appear during transaction it will automatically rollback and Also as I am using select_for_update so it will lock the row until the transaction get succeeded or failed.
If anyone have better suggestion then kindly share it.

How to check if Django form contains any data?

I have Django function view with two forms inside. What is the best solution to detect which form has data typed by user? I know how form.is_valid() works, but still I want to check firstly which form was filled with data.
My code:
def edit_profile_view(request):
if request.method == "POST":
edit_form = EditProfileForm(request.POST)
pass_form = ChangePasswordForm(request.POST)
# here I want to detect which form has data inside,
# and then save this form
else:
edit_form = EditProfileForm()
pass_form = ChangePasswordForm()
template = get_template("profiles/profile_edit.html")
variables = RequestContext(request, {'edit_form': edit_form, 'pass_form': pass_form})
output = template.render(variables)
return HttpResponse(output)
Just have two different actions/views for the forms then the form that has data is the one that the user clicked submit on.
You could, like you say, just check what the form errors actually are or make a method on your forms for is_filled_in but this all seems overkill to me.

How to keep track of Form field changes in Flask-WTF?

I have model with members field as shown below:
class Team(db.Model):
--- some fields ---
members = ListProperty(db.Key) # Using App Engine datastore as backend.
I am using Flask-WTFforms to create form using this model. While creating new Team, user will select some members in the form and save it. User can also edit the Team form and make changes to the members field(Can add or remove members). I wanted to check how many members added or deleted by comparing it with previous data stored in members field. Same applies for other fields also.
I used sessions to achieve this:
def edit_team(key):
k = db.Key(key)
team = db.get(k)
form = TeamForm(obj = team)
if not form.is_submitted(): # Indicates GET request
session[str(g.user.user_id() + 'prev_members'] = form.members.data
if form.validate_on_submit():
form.populate_obj(project)
# I will use session data with new form.members.data to do further processing.
Is this the right way to handle this scenario?
Thank you for any help..
the problem with your code is
team = db.get(k)
form = TeamForm(obj = team)
if the request was GET, the object's data has to be loaded from the model. however, if the request was POST (or PUT, PATCH) it means that you need to read the request body to form to do proper updates on the model. it seems like you're using k variable as a key to the indicator of the model.
k = db.Key(key)
team = db.get(k)
if request.method == "GET":
# create form from the model
form = TeamForm(obj = team)
elif request.method == "POST":
# update model with the form
form = TeamForm() #flask-wtf automatically reads from request object
# validate, update, delete, ...

POST in django. How does a user update?

I'm brand new to django and fairly new to programming in general. I've done the django tutorial and searched the web for an answer to this question, but to no avail, so now I'm here. I am confused how post works with django. All of the tutorials I've looked at how have a return function in views that displays the webpage. I get that. But then how does a user update data if the page is being rendered from that return statement? After the return there can't be any more updates because the function stops, right? What am I missing here? Any help would be greatly appreciated, I'm getting fairly desperate here.
One pattern for Django views (by no means the only pattern) is to check the request method (GET or POST) at the beginning of the view. If it is POST, then handle the incoming data (before the view returns), and then return either a rendered template, or a redirect.
def view_function(request):
if request.method == 'POST':
if data_is_valid(request.POST):
save_data(request.POST)
return HttpResponseRedirect('/somewhere/good')
else:
return render('template', {'errors': what_went_wrong}
else:
return render('template')
The user updates data in the logic of the view function. That is to say, if the user wishes to update something, you place the update logic in the view function before the return. For example, you would do this:
def update(request):
item = <some model>.objects.get(<something>)
<more code>
return <something>
Usually an edit view function contains two parts -- one for updating data, and the other for displaying the update form. For example,
def user_edit(request):
if request.method == 'POST': # is this a save action?
# save the user data
user_id = request.POST.get('user_id')
username = request.POST.get('username')
description = request.POST.get('description')
user = User.objects.get(id=user_id)
user.username = username
user.description = description
user.save()
return HttpResponseRedirect('/user/') # redirect to index
else:
# show the edit form
user_id = request.GET.get('user_id')
user = User.object.get(id=user_id)
return render_to_response('/user/edit.html', { 'user': user })
There are many different choices for the if request.method == 'POST' line. You can also use if request.POST.get('user_id') to check if specified field is set, to determine if this is a save action.

Categories

Resources