Value Error for Foregin key field - django

I am trying to insert data but am getting ValueError while inserting due to ForeignKey.
class Test(models.Model):
test_name = models.CharField(max_length=20, unique=True)
test_code = models.SlugField(max_length=10, name='Code',unique=True)
referance_value = models.CharField(name='Referance', max_length=20)
def __str__(self):
return self.test_name
class TestTaken(models.Model):
app_code = models.CharField(max_length=20,unique=True)
user_name = models.CharField(name='Username',max_length=20)
test_names = models.ForeignKey(Test, on_delete=models.CASCADE)
result_value = models.CharField(name='ResultValue',max_length=20)
def __str__(self):
return self.app_code
Below is my View.py
def alltestdata(request):
if request.method == 'POST':
app_code = request.POST.getlist('app_code')
test_name = request.POST.getlist('name')
test_list = request.POST.getlist('test_list')
for i, j , k in zip(app_code, test_name, test_list):
book = TestTaken(app_code=i, ResultValue=j, test_names=k, Username=request.user.username)
book.save()
return redirect('lab:Dashboard')
Am geting following error
ValueError: Cannot assign "'eeeee'": "TestTaken.test_names" must be a "Test" instance.

The error holds the answer to your question: test_names is a ForeignKey, not a string. To set it from a name, you first need to find the key into the Test table. This can be done with a get or get_or_create, depending on how you want to handle missing tests.
NOTE: test_names is not a very good name for that ForeignKey field and probably caused this confusion. It shouldn't be plural, and points to a Test object, not just a name. You probably want something more like test
There is some additional confusion in your code. First, you seem to have swapped values in your inner iteration (j gets its value from test_name and is then applied to ResultValue, while k comes from test_list but goes to test_names instead). You can avoid confusion like this by using more explicit variable names. The second source of confusion is in the variable names app_code, test_name, and test_list, all of which seem to be lists, but only one of them has a name that seems to reflect this.
Combining these points into code, try something like the following. Note that I have changed some of the names of variables to reflect what I think you intended, and I have used a simple get_or_create, while you might want something else. Adjust to suit your needs:
# in your model
class Test(models.Model):
test_name = models.CharField(max_length=20, unique=True)
test_code = models.SlugField(max_length=10, name='Code',unique=True)
referance_value = models.CharField(name='Referance', max_length=20)
def __str__(self):
return self.test_name
class TestTaken(models.Model):
app_code = models.CharField(max_length=20,unique=True)
user_name = models.CharField(name='Username',max_length=20)
test = models.ForeignKey(Test, on_delete=models.CASCADE)
result_value = models.CharField(name='ResultValue',max_length=20)
def __str__(self):
return self.app_code
# in View.py
def alltestdata(request):
if request.method == 'POST':
app_codes = request.POST.getlist('app_code')
test_names = request.POST.getlist('name')
scores = request.POST.getlist('test_list')
for code, test_name, score in zip(app_codes, test_names, scores):
test_obj, _ = Test.objects.get_or_create(test_name=test_name)
book = TestTaken(app_code=code, ResultValue=score, test=test_obj, Username=request.user.username)
book.save()
return redirect('lab:Dashboard')

Related

How to fix QuerySet' object has no attribute issue?

I need to create the new object or just update if already existing. I receive: QuerySet' object has no attribute "seat". Don't know what I'm doing wrong.
models:
class rows_and_seats(models.Model):
movie = models.ForeignKey(Movies, on_delete=models.CASCADE)
row = models.CharField(max_length = 1)
number = models.IntegerField()
def __str__(self):
return f'{self.movie}'
class Reservation(models.Model):
customer = models.ForeignKey(User, on_delete=models.CASCADE)
movie = models.ForeignKey(Movies, on_delete=models.CASCADE)
seat = models.ManyToManyField(rows_and_seats)
ordered = models.DateTimeField(default=datetime.now().strftime("%Y-%m-%d %H:%M:%S"), blank=True, null=True)
def __str__(self):
return f'{self.customer.username}:{self.movie.title}:{self.ordered}'
views
#login_required
def buy_seats(request, pk):
if request.method == "POST" and request.session.get("seats"):
seats = request.session.pop("seats")
movie = Movies.objects.get(pk=pk)
customer = User.objects.get(pk=request.user.id)
for s in seats:
user_reserved_seats = rows_and_seats.objects.get(movie=movie, row=s[:1], number=int(s[2:]))
reservation_check = Reservation.objects.filter(customer=customer, movie=movie)
if reservation_check.exists():
reservation_check.seat.add(user_reserved_seats)
else:
new_reservation = Reservation.objects.create(customer=customer, movie=movie)
new_reservation.seat.add(user_reserved_seats)
messages.success(request,"You have succesfully reserved the seats.")
return redirect("home")
return redirect("home")
My goal is to keep rows_and_seat in manyTomany in order to display only one reservation of user in admin panel, instead of the list of repeating itself titles.
You can access the value after the exists() check:
if reservation_check.exists():
reservation_check.first().seat.add(user_reserved_seats)
else:
new_reservation = Reservation.objects.create(customer=customer, movie=movie)
new_reservation.seat.add(user_reserved_seats)
Maybe you can use something like get_or_create:
user_reserved_seats = rows_and_seats.objects.get(movie=movie, row=s[:1], number=int(s[2:]))
reservation, created = Reservation.objects.get_or_create(
customer=customer, movie=movie,
)
reservation.seat.add(user_reserved_seats)
Also you might be looping over the seats too many times, maybe you can add all the seats in only one assignment.

how to fix "IntegrityError at /prog UNIQUE constraint failed: grading_program_of_study.student_id" in django

i am setting up a django applcation in which am using one to one field when i add student detial from the backend it works well but form a frontend form it gives the following error "IntegrityError at /prog
UNIQUE constraint failed: grading_program_of_study.student_id
"
//////////////my view code////////////////
def prog(request):
if request.method == 'POST':
if request.POST['program_name'] and request.POST['date_of_entry'] and request.POST['faculty']and request.POST['department'] and request.POST['program_type'] and request.POST['date_of_complition']:
Program_of_study = program_of_study()
Program_of_study.program_name = request.POST['program_name']
Program_of_study.date_of_entry = request.POST['date_of_entry']
Program_of_study.faculty = request.POST['faculty']
Program_of_study.department = request.POST['department']
Program_of_study.department = request.POST['program_type']
Program_of_study.date_of_complition = request.POST['date_of_complition']
Program_of_study.save()
return redirect('home',{'sucess':'Program added sucessfully'})
else:
return render(request,'grading/home.html')
else:
return render(request,'grading/home.html')
########### my model code################################
class program_of_study(models.Model):
student = models.OneToOneField(student_details, on_delete=models.CASCADE,default = 1)
program_name = models.CharField(max_length=50)
date_of_entry = models.DateField()
faculty = models.CharField(max_length=50)
department = models.CharField(max_length=50)
program_type = models.CharField(max_length=50)
date_of_complition = models.DateField()
def __str__(self):
return self.program_name
Your problem is the default value in the student field. Since you have a OneToOne relation, you can't repeat values, so you can't have a default.
student = models.OneToOneField(student_details, on_delete=models.CASCADE, default = 1)
What you can do to solve the issue is change the field type to ForeignKey, or remove the default value.
thank God i have fixed the problem with just a single line of code the error was that i was trying to save the data as a string instead of as an integer
############### the solution to the problem
Program_of_study.student = student_details.object.latest(id)

django sort on calculated model field -- can I use .extra?

I have the model below. I want to order by percent_vote. I know I could calculate the value and save to a new field in the model, but I prefer not to go that way. Is there some way to use .extra method to do this?
Django 1.6, sqlite3
class HallOfFame(models.Model):
player = models.ForeignKey(Master)
year = models.IntegerField(db_index=True)
voted_by = models.CharField(max_length=30)
ballots_cast = models.IntegerField()
votes_needed = models.IntegerField()
votes_received = models.IntegerField(db_index=True)
inducted = models.BooleanField(db_index=True)
category = models.CharField(max_length=30, db_index=True)
needed_note = models.CharField(max_length=75, blank=True, null=True)
def __unicode__(self):
return "%s %s" % (self.player.name_first, self.player.name_last)
def percent_vote(self):
try:
return self.votes_received/float(self.ballots_cast)
except ZeroDivisionError:
return 0
Yes, it seems you can do something like this, but this may depend on the your database backend ( this should work for PostgreSQL ):
q = HallOfFame.objects.extra(select={'percent_vote_integer': "votes_received/ballots_cast", 'percent_vote_remainder': "votes_received%ballots_cast"})
q = q.extra(order_by = ['percent_vote_integer', percent_vote_remainder])
I ended up solving this issue with the code below. #Emil Davtyan's answer didn't work for me, and I wanted to figure out a more general solution.
def home(request):
hall = HallOfFame.objects.filter(inducted=True, voted_by='BBWAA')
hall_sorted = sorted(hall, key=lambda member: member.percent_vote, reverse=True)[:20]
return render_to_response('top_lists.html', {'hall': hall_sorted })
the model has this:
#property
def percent_vote(self):
try:
return float(self.votes_received)/self.ballots_cast
except ZeroDivisionError:
return 0

How can I compare 2 fields and input a result in Django

I know this is probably very basic stuff but I'm really having a tough time figuring it out. I have an app that stores sports forecasts for users, so they input the home team, it's score and the visiting team with it's score. The idea is for the app to determine whether the result was a home win, a tie or an away win by comparing the scores on both input boxes.
This is my view:
def inicio(request):
if request.method == "POST":
form = Pronosticos(request.POST)
if form.is_valid():
pronostico = PartidosUsuarios.objects.get_or_create(idUsuario=request.user, idPartido=request.POST.get("idPartido", ""), PaisL=request.POST.get("PaisL", ""), Local=request.POST.get("Local", ""), Visita=request.POST.get("Visita", ""), PaisV=request.POST.get("PaisV", ""), Capturado="Si")
if pronostico.Local > pronostico.Visita:
pronostico.Resultado = "Local"
elif pronostico.Visita > pronostico.Local:
pronostico.Resultado = "Visita"
elif pronostico.Local == pronostico.Visita:
pronostico.Resultado = "Empate"
return render(request, "brasil/inicio.html")
partidos_fifa = PartidosFifa.objects.order_by("Partido")[:64]
context = {"partidos_fifa": partidos_fifa}
return render(request, "brasil/inicio.html", context)
The form:
class Pronosticos(ModelForm):
class Meta:
model = PartidosUsuarios
fields = ["idPartido", "PaisL", "Local", "Visita", "PaisV"]
and the model:
class PartidosUsuarios(models.Model):
idUsuario = models.OneToOneField(User)
idPartido = models.CharField(max_length=20)
PaisL = models.CharField(max_length=250)
Local = models.IntegerField(max_length=11, default=0)
Visita = models.IntegerField(max_length=11, default=0)
PaisV = models.CharField(max_length=250)
Resultado = models.CharField(max_length=250)
Puntos = models.IntegerField(max_length=11, default=0)
Capturado = models.CharField(max_length=10, default="No")
def __unicode__(self):
return unicode(self.idPartido)
The field in question aka where i want the result to be stored is called "Resultado"
Everything works as it should except for this part where i've been getting this error:
AttributeError at /inicio/
'tuple' object has no attribute 'Local'
It's complaining about this line:
if pronostico.Local > pronostico.Visita:
Any help will be greatly appreciated, thanks!
The problem here is the return value from get_or_create(). From the documentation:
Returns a tuple of (object, created), where object is the retrieved or created object and created is a boolean specifying whether a new object was created.
So try this instead:
pronostico, _ = PartidosUsuarios.objects.get_or_create(...)

Want to make sure object not in queryset before adding it

My "Event" object has a "Name" field. There is the possibility that the name is wrong, so a user may suggest a new name. That name gets put into the event's "suggestedN" list. However, I don't want there to be duplicates of one suggestion in that list. I felt like this was a straightforward problem, but for some reason am not finding much success.
Here is how my view currently looks:
#login_required
def suggestName(request):
name = request.POST['name'].strip()
event_id = request.POST['event_id']
try:
e = Event.objects.get(event_id = event_id)
except Event.DoesNotExist:
e = customEvent.objects.get(event_id = event_id)
if name in e.suggestedN.all():
pass
else:
(some code)
Is my if name in e.suggestedN.all() statement wrong?
Here's a brief view of my Event's model:
class Event(models.Model):
def __unicode__(self):
return self.title
suggestedN = models.ManyToManyField('suggestedName', blank = 'TRUE', null = 'TRUE')
class suggestedName(models.Model):
def __unicode__(self):
return self.name
name = models.CharField(max_length=200, blank = 'TRUE', null = 'TRUE')
votes = models.IntegerField(default = 0)
You should use the name attribute on m2m not the m2m itself to compare
#login_required
def suggestName(request):
name = request.POST['name'].strip()
event_id = request.POST['event_id']
try:
e = Event.objects.get(event_id = event_id)
except Event.DoesNotExist:
e = customEvent.objects.get(event_id = event_id)
if name in e.suggestedN.values_list('name', flat=True):
pass
else:
(some code)