Manage ModelManyToMany request in views.py - python

I have a ModelManyToMany selector in my html.
(I can't post images so, here is the url to image: https://i.stack.imgur.com/HDhde.png)
I want to catch the user's selections with my POST method in my views.py
views.py
class userPageView(TemplateView):
template_name = 'user.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['edit_profile_form'] = EditProfileForm(prefix='edit')
return context
def post(self, request, *args, **kwargs):
edit_name = request.POST.get('edit-name')
edit_two_factors_auth = request.POST.get('edit-two_factors_auth')
edit_coins = request.POST.get('edit-coins')
if request.method == "POST":
if 'profileButton' in request.POST:
if edit_name and (edit_name != request.user.name):
request.user.name = edit_name
request.user.save()
print(edit_coins)
return render(request, 'user.html')
models.py
class Usuario(AbstractUser):
name = models.CharField(max_length=12, help_text="The name must be between 2 and 12 characters")
email = models.EmailField(max_length=60, unique=True, help_text="The email must be between 5 and 30 characters")
password = models.CharField(max_length=78)
change_password_code = models.CharField(blank=True,max_length=15)
activated = models.BooleanField(default=False)
activated_code = models.CharField(default="",max_length=15)
ip = models.CharField(blank=True,max_length=15)
last_login = models.DateField(default=now)
wallets = models.ManyToManyField(Wallet)
coins = models.ManyToManyField(Coin)
avatar = models.CharField(blank=True,default="bitcoin.png",max_length=15)
delete_code = models.CharField(default="",max_length=9,blank=True)
two_factors_auth = models.BooleanField(default=False)
two_factors_auth_code = models.CharField(default="",max_length=12,blank=True)
fingerprint = models.CharField(max_length=64,blank=True)
The print in my views.py only returns me the last selection, but not all the set of choices that the user has done.
I want to save all coins selections by the users in his coins field

you must change this line
edit_coins = request.POST.get('edit-coins')
to
edit_coins = request.POST.getlist('edit-coins')
and its works. after that edit_conis is a list contain all items user selected.

Related

how to solve unusual logical error in django

So I made this transaction process that will pass with the help of phone number. But the logic is not working properly. sender side is deducting way more numbers that i want to send. for example, if i want to send 100, it's deducting 500 and receiver is not receiving the amount.
can anyone help me with this?
models.py
class extenduser(models.Model):
ID= models.IntegerField(null=True, default=None)
FirstName= models.CharField(max_length= 50)
MiddleName= models.CharField(max_length=50)
LastName= models.CharField(max_length=50)
phone= models.CharField(max_length=20)
user= models.OneToOneField(User, on_delete=models.CASCADE)
class Status (models.Model):
user_name = models.CharField(max_length=150, default=None)
account_number = models.IntegerField()
balance = models.IntegerField()
phone_number= models.CharField(max_length=20,default=None)
class MoneyTransfer(models.Model):
enter_your_user_name = models.CharField(max_length = 150, default = None)
enter_the_destination_account_number = models.IntegerField()
enter_the_destination_phone_number=models.CharField(max_length=20, default=None)
enter_the_amount_to_be_transferred_in_INR = models.IntegerField()
views.py
def randomGen():
# return a 6 digit random number
return int(random.uniform(100000, 999999))
def index(request):
try:
curr_user = Status.objects.get(user_name=request.user) # getting details of current user
except:
# if no details exist (new user), create new details
curr_user = Status()
curr_user.account_number = randomGen() # random account number for every new user
curr_user.balance = 0
curr_user.user_name = request.user
curr_user.phone_number= extenduser.phone
curr_user.save()
return render(request, "epayapp/index.html", {"curr_user": curr_user})
def TransferMoney(request):
if request.method == "POST":
form = forms.MoneyTransferForm(request.POST)
if form.is_valid():
form.save()
curr_user = models.MoneyTransfer.objects.filter(enter_your_user_name=request.user).first()
dest_user_acc_num = curr_user.enter_the_destination_account_number
dest_phone_num= curr_user.enter_the_destination_phone_number
temp = curr_user # NOTE: Delete this instance once money transfer is done
dest_user = models.Status.objects.get(account_number=dest_user_acc_num)
dest_phn= models.Status.objects.get(phone_number= dest_phone_num)
transfer_amount = curr_user.enter_the_amount_to_be_transferred_in_INR
curr_user = models.Status.objects.get(user_name=request.user)
# Now transfer the money!
curr_user.balance = curr_user.balance - transfer_amount
dest_phn.balance = dest_phn.balance + transfer_amount
curr_user.save()
dest_user.save()
# Save the changes before redirecting
temp.delete() # NOTE: Now deleting the instance for future money transactions
return redirect(index)
else:
form = forms.MoneyTransferForm()
return render(request, "epayapp/Transfer_money.html", {"form": form})

Django - NOT NULL constraint failed

I'm currently working on a Django app that will parse the contents of an uploaded log file to the associated database in my Django project. I've managed to get it all running as expected except it won't associate my uploaded data with the model's ForeignKey. I can assign null=True which resolves the integrity error but then of course, it doesn't assign any of the uploaded data to that ForeignKey. Here's the code:
models.py
class Case(models.Model):
case_ref = models.CharField(max_length=8)
oic = models.CharField(max_length=50)
subject = models.CharField(max_length=100)
submitted_date = models.DateTimeField(default=datetime.now, blank=True)
def get_absolute_url(self):
return reverse('case_list', kwargs={'pk': self.pk})
def __str__(self):
return self.case_ref + " " + self.subject
class TeamviewerLogs(models.Model):
case = models.ForeignKey(Case, on_delete=models.DO_NOTHING)
teamviewer_id = models.IntegerField()
teamviewer_name = models.TextField()
connection_start = models.TextField()
connection_end = models.TextField()
local_user = models.TextField()
connection_type = models.TextField()
unique_id = models.TextField()
def get_absolute_url(self):
return reverse('case_list', kwargs={'pk': self.pk})
def __str__(self):
return str(self.teamviewer_id) + " - " + str(self.teamviewer_id)
forms.py
class UploadLog(forms.ModelForm):
file = forms.FileField()
class Meta:
model = TeamviewerLogs
fields = [
'file'
]
views.py
def add_logs(request, pk):
case = get_object_or_404(Case, pk=pk)
if request.method == 'POST':
form = UploadLog(request.POST, request.FILES)
if form.is_valid():
teamviewer = form.save(commit=False)
teamviewer.case = case
log_file = request.FILES['file']
log_file = filter(None, (line.rstrip() for line in log_file))
for lines in log_file:
split = lines.decode('utf-8').split('\t')
teamviewer_id = split[0]
teamviewer_name = split[1]
connection_start = split[2]
connection_end = split[3]
local_user = split[4]
connection_type = split[5]
unique_id = split[6]
teamviewer = TeamviewerLogs(teamviewer_id=teamviewer_id, teamviewer_name=teamviewer_name,
connection_start=connection_start, connection_end=connection_end,
local_user=local_user, connection_type=connection_type, unique_id=unique_id)
teamviewer.save()
return redirect('tv_log_details', pk=case.pk)
form.save()
else:
form = UploadLog()
return render(request, 'teamviewer/add_logs.html', {'form': form})
But when I click to upload the file I'm hit with:
When it tries to execute teamviewer.save().
I've been trying to resolve this issue for hours and have tried so many different variations of answers from Stackoverflow or previous code I've used that has worked for different models but I've hit a brick wall...hard!
Any help anyone can offer would be greatly appreciated.
Ok, so here's an example of the concept I've suggested in the comments.
I've got a view which passes some data to the a form;
class ListingDetailView(DetailView):
""" Listing detail page """
model = Listing
template_name = 'listing.html'
def get_form_kwargs(self):
"""Return the kwargs for the form"""
kwargs = {}
initial = {
'listing': self.object,
}
kwargs['initial'] = initial
return kwargs
def get_form(self):
form = ApplicationSignupForm(
**self.get_form_kwargs()
)
return form
def get_context_data(self, **kwargs):
""" Add our form to the context """
context = super().get_context_data(**kwargs)
context['form'] = self.get_form()
return context
The form then makes use of that initial data and sets the field it relates to as hidden. I don't validate this data, but I'll try to show how you might do that;
class ApplicationSignupForm(forms.ModelForm):
class Meta:
""" Setup the form """
fields = (
'listing',
...
)
model = Application
widgets = {
'listing': forms.HiddenInput()
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
initial_data = kwargs['initial']
self.listing = initial_data.get('listing')
def clean(self):
"""
Custom form cleaning
"""
cleaned_data = super().clean()
listing = cleaned_data.get('listing')
if listing != self.listing:
self.add_error('listing', "You can't modify this value")
return cleaned_data

AttributeError at /sample/ : 'QuerySet' object has no attribute 'no_of_ques'

I am making a quiz application, for result calculation I have written logic ..If the value of answer stored in question model is equal to the answer chosen by user then , when user submits each question , score is incrementing by one, but I've failed to build this logic as am a new user to django please help.
Models.py : question along with its 4 options and the correct answer is in question model(These fields are entered by the user who creates a quiz by filling a form). Answer submitted by user is in answer model(This field is entered by user who takes quiz). score is stored in result model.
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
class quiztitle(models.Model):
Quiz_id = models.AutoField(primary_key=True)
Quiz_title = models.CharField(max_length=600)
User = settings.AUTH_USER_MODEL
User_id= models.ForeignKey(User, on_delete=models.CASCADE)
no_of_ques = models.IntegerField(default=10)
class question(models.Model):
Qid = models.AutoField(primary_key=True)
User = settings.AUTH_USER_MODEL
User_id = models.ForeignKey(User,on_delete=models.CASCADE)
Quiz_id = models.ForeignKey(quiztitle,on_delete=models.CASCADE)
Qques = models.TextField()
Qoption1 = models.TextField()
Qoption2 = models.TextField()
Qoption3 = models.TextField()
Qoption4 = models.TextField()
QAnswer = models.TextField()
class answer(models.Model):
Ansid = models.AutoField(primary_key=True)
Qid = models.ForeignKey(question,on_delete=models.CASCADE)
Quiz_id = models.ForeignKey(quiztitle, on_delete=models.CASCADE)
User = settings.AUTH_USER_MODEL
User_id = models.ForeignKey(User, on_delete=models.CASCADE)
Answer = models.TextField()
class result(models.Model):
result = models.AutoField(primary_key=True)
Quiz_id = models.ForeignKey(quiztitle, on_delete=models.CASCADE)
User_id = models.ForeignKey(User, on_delete=models.CASCADE)
score = models.FloatField()
def __str__(self):
return str(self.pk)
here's views.py file
from django.shortcuts import render,redirect,HttpResponseRedirect
from .models import question ,quiztitle ,answer ,result
from django.contrib.auth.models import User
from .forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from .decorators import unauthenticated_user,allowed_users
from django.contrib.auth.models import Group
def home_page(request):
return render(request,'Home.html')
def forbidden(request):
return render(request,'error403.html')
#unauthenticated_user
def registerPage(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save()
username = form.cleaned_data.get('username')
group = Group.objects.get(name='Student')
user.groups.add(group)
messages.success(request, 'account has been created successfully for username' + username)
return redirect('login')
context = {'form':form}
return render(request,'register.html',context)
#unauthenticated_user
def handle_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request,user)
if request.user.groups.filter(name="Teacher"):
return redirect('quizmaker')
else:
return redirect('student')
else:
messages.info(request, 'Incorrect Username or Password')
context = {}
return render(request, 'login.html', context)
def logoutUser(request):
logout(request)
return redirect('home')#redirect to login page
#login_required(login_url='home')
#allowed_users(allowed_roles=['Teacher','Head'])
def handle_quiz(request):
if request.method=="POST":
# get post parameters
Quiz_title = request.POST.get('Quiz_title')
Quiz_id = request.POST.get('Quiz_id')
no_of_ques = request.POST.get('no_of_ques')
Qid = request.POST.get('Qid')
Qques = request.POST.get('Qques')
Qoption1 = request.POST.get('Qoption1')
Qoption2 = request.POST.get('Qoption2')
Qoption3 = request.POST.get('Qoption3')
Qoption4 = request.POST.get('Qoption4')
QAnswer = request.POST.get('QAnswer')
title = quiztitle(Quiz_title=Quiz_title,Quiz_id=Quiz_id,no_of_ques=no_of_ques)
title.User_id=request.user
title.save()
detail = question(Qid=Qid,Qques=Qques,Qoption1=Qoption1,Qoption2=Qoption2,Qoption3=Qoption3,Qoption4=Qoption4,QAnswer=QAnswer)
detail.User_id=request.user
detail.Quiz_id = title
detail.save()
messages.success(request,'Your question has been added succesfully')
return HttpResponseRedirect('/quizmaker')
return render(request,"createquiz.html")
#login_required(login_url='login')
#allowed_users(allowed_roles=['Student'])
def handle_response(request):
if request.user.is_authenticated:
myuser = User.objects.all()
title = quiztitle.objects.all()
data = question.objects.all()
if request.method == 'POST':
Answer=request.POST.get('Answer')
response = answer(Answer=Answer)
response.User_id = request.user
response.Quiz_id = request.quiztitle
response.Qid = request.question
Answer.save()
return HttpResponseRedirect('/student')
return render(request,"student.html",context={"messages": data ,"topic": title ,"user1": myuser})
def handle_result(request):
if request.user.is_authenticated:
quiz = quiztitle.objects.all()
ques = question.objects.all()
ans = answer.objects.all()
score = 0
if request.method == 'POST':
while(score<=quiz.no_of_ques):
if (ques.objects.QAnswer == ans.objects.Answer):
score += 1
print(score)
sc = request.POST('score')
res = result(sc=score)
res.User_id = request.user
res.Quiz_id = request.quiztitle
result.save()
return HttpResponseRedirect('/sample')
return render(request, "sample.html", context = {"ques":ques , "ans":ans})
In your handle_result function, you have:
quiz = quiztitle.objects.all()
# ...
while(score<=quiz.no_of_ques):
The issue here is that:
The quiz variable is not ONE quiz, it's ALL of them. So it's not an instance, it's a list of instances (technically, a QuerySet of instances)
Therefore, you cannot call quiz.no_of_ques, because quiz is not an instance
That's why you're getting the 'QuerySet' object has no attribute 'no_of_ques' error. Either query one specific instance, or query them all and loop over them.
In views.py handle_result function,
replacing
quiz = quiztitle.objects.all()
with
quizno = quiztitle.objects.values_list('no_of_ques', flat=True)
#....
while(score<=quizno):
it resolves the error 'QuerySet' object has no attribute 'no_of_ques' as it queries one instance i.e no_of_ques

Passing logged in user to form

I am trying to pass logged in user to form that i would like to save.
forms.py
class SpotForm(ModelForm):
def __init__(self, *args, **kwargs):
super(SpotForm, self).__init__(*args, **kwargs)
self.fields['gross_weight'].widget = forms.NumberInput(attrs={'min':0})
self.fields['volume'].widget = forms.NumberInput(attrs={'min': 0})
class Meta:
model = Spot
fields = [
'gross_weight','volume','origin_country','origin_port',
'dest_country','dest_port','ship_week','requestor'
]
models.py
class Stakeholder(models.Model):
user = models.OneToOneField(User,null=True,blank=True,on_delete=models.CASCADE)
company_name = models.CharField(max_length=15)
mail = models.CharField(max_length=40)
def __str__(self):
return self.mail
class Spot(models.Model):
STATUSES = (
('Open','Open'),
('Closed','Closed')
)
gross_weight = models.FloatField(null=False,default=0,validators=[MinValueValidator(0)])
volume = models.FloatField(null=False,default=0,validators=[MinValueValidator(0)])
origin_country = models.CharField(
validators=[RegexValidator(regex='[A-Z]{2}', message='Country code is two letters')], max_length=2,null=True)
origin_port = models.CharField(
validators=[RegexValidator(regex='[A-Z]{3}', message='Port code is three letters')], max_length=3,null=True)
dest_country = models.CharField(
validators=[RegexValidator(regex='[A-Z]{2}', message='Country code is two letters')], max_length=2,null=True)
dest_port = models.CharField(
validators=[RegexValidator(regex='[A-Z]{3}', message='Port code is three letters')], max_length=3,null=True)
time_registered = models.DateField(default=timezone.now)
spot_status = models.CharField(max_length=6,default='Open', choices=STATUSES)
ship_week = models.CharField(max_length=2,null=True)
requestor = models.ForeignKey(Stakeholder,null = True,on_delete=models.CASCADE)
def __str__(self):
return self.origin_country + self.origin_port + '-' + self.dest_country +self.dest_port + '-' + self.ship_week
views.py
def register_spot(request):
my_user = Stakeholder.objects.get(user=request.user)
form = SpotForm()
if request.method =='POST':
print("print",request.POST)
form = SpotForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
print(form.errors)
context = {'form': form}
return render(request, 'spotrequesting/register_spot.html', context)
When i submit the form i am getting an error in command prompt stating "This field is required" for "requestor". After that - dropdown list for this field come up on screen and i can select out of two registered users i have. But even selecting something from this list and again submitting the form is giving me the same error.
Checking "my_user" variable - it is showing me that i am logged in.
Is there a way to pass to "requestor" field currently logged in user?
I was able to get the form saved only by deleting "requestor" from "fields" in SpotForm (which gave me "None" in the end for this field in database) but that's not the desired outcome.
Any suggestion would be highly appreciated.
You are not really passing the stakeholder instance to the requestor field in the form are you? So you will have to do:
form = SpotForm(requestor = my_user)

Django: Setting values of certain attributes in the database using views?

I have a form in my application which has a hidden form field, the value of which I want to set in my corresponding view after submitting the form.
forms.py
class EvangelizedForm(forms.ModelForm):
first_name = forms.CharField(help_text="First Name")
last_name = forms.CharField(help_text="Last Name")
email = forms.CharField(help_text="Email ID")
mobile_no = forms.CharField(help_text="Mobile number")
twitter_url = forms.CharField(help_text="Twitter URL")
twitter_followers = forms.CharField(widget = forms.HiddenInput()) #Hidden form field
class Meta:
model = Evangelized
fields = ('first_name','last_name', 'twitter_url', 'email', 'mobile_no')
models.py
class Evangelized(models.Model):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField()
mobile_no = models.CharField(unique=True, max_length = 10, validators=[RegexValidator(regex='^\w{10}$', message='Mobile number should be strictly of 10 digits.')])
twitter_url = models.CharField(unique=True, max_length=128)
twitter_followers = models.CharField(max_length = 128)
views.py
def fillform(request):
follower_count = '250'
if request.method == 'POST':
form = EvangelizedForm(request.POST)
if form.is_valid():
form.fields['twitter_followers'] = follower_count
form.save(commit=True)
return index(request)
else:
form.errors
else:
#form = EvangelizedForm()
if request.user.is_authenticated():
form = EvangelizedForm(initial={'first_name': request.user.first_name,
'twitter_url': 'https://twitter.com/' + request.user.username,
'last_name': request.user.last_name})
else:
form = EvangelizedForm()
context = RequestContext(request,
{'request': request,
'user': request.user, 'form':form})
#return render(request, 'rango/fillform.html', {'form': form, 'context_instance':context})
return render_to_response('rango/fillform.html',
context_instance=context)
Basically, I'm trying to set the value of twitter_followers (which is a hidden form field in forms.py) in my index view, by:
follower_count = '250'
..
..
form.fields['twitter_followers'] = follower_count
By doing this, I'm expecting the value of 'twitter_followers' in the database after submitting the form to be '250'. However, this approach doesn't seem to be working.
What's the right way to set values to certain attributes in the database manually using views?
You need to set it on the model instance, which is the result of form.save. That's the main reason for the commit argument in the first place.
if form.is_valid()
obj = form.save(commit=True)
obj.twitter_follower = follower_count
obj.save()
You can override the save method of the form, with something like this:
def save(self, *args, **kwargs)
twitter_followers = kwargs.pop('twitter_followers', 0)
self.instance.twitter_followers = twitter_followers
super(Evangelized, self).save(args, kwargs)
And then in the view just have to call in this way:
form.save(twitter_followers=250)

Categories