Django update MySQL database issue involving foreign keys - python

Good morning all,
I have the following two models:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class StraightredTeam(models.Model):
teamid = models.IntegerField(primary_key=True)
teamname = models.CharField(max_length=36)
country = models.CharField(max_length=36,null=True)
stadium = models.CharField(max_length=36,null=True)
homepageurl = models.CharField(max_length=36,null=True)
wikilink = models.CharField(max_length=36,null=True)
teamcode = models.CharField(max_length=5,null=True)
teamshortname = models.CharField(max_length=24,null=True)
currentteam = models.PositiveSmallIntegerField(null=True)
def natural_key(self):
return self.teamname
class Meta:
managed = True
db_table = 'straightred_team'
class StraightredFixture(models.Model):
fixtureid = models.IntegerField(primary_key=True)
home_team = models.ForeignKey('straightred.StraightredTeam', db_column='hometeamid', related_name='home_fixtures')
away_team = models.ForeignKey('straightred.StraightredTeam', db_column='awayteamid', related_name='away_fixtures')
fixturedate = models.DateTimeField(null=True)
fixturestatus = models.CharField(max_length=24,null=True)
fixturematchday = models.IntegerField(null=True)
spectators = models.IntegerField(null=True)
hometeamscore = models.IntegerField(null=True)
awayteamscore = models.IntegerField(null=True)
homegoaldetails = models.TextField(null=True)
awaygoaldetails = models.TextField(null=True)
hometeamyellowcarddetails = models.TextField(null=True)
awayteamyellowcarddetails = models.TextField(null=True)
class Meta:
managed = True
db_table = 'straightred_fixture'
The following view works perfectly:
#csrf_exempt
def updateteams(request):
if request.user.is_authenticated():
xmlsoccer = XmlSoccer(api_key='XYZ', use_demo=True)
teams = xmlsoccer.call_api(method='GetAllTeams')
numberOfTeamsUpdated = 0
for team in teams:
if 'Team_Id' in team.keys():
teamUpdate = StraightredTeam(teamid=team['Team_Id'],teamname=team['Name'],stadium=team['Stadium'])
teamUpdate.save()
numberOfTeamsUpdated = numberOfTeamsUpdated + 1
return HttpResponse(str(numberOfTeamsUpdated) + " team/s have been added/updated.")
else:
return HttpResponse("You must be logged in to update teams.")
However, the following view does not work:
#csrf_exempt
def updatefixtures(request):
if request.user.is_authenticated():
xmlsoccer = XmlSoccer(api_key='XYZ', use_demo=True)
fixtures = xmlsoccer.call_api(method='GetFixturesByLeagueAndSeason',
seasonDateString='1516',
league='Scottish Premier League')
numberOfFixturesUpdated = 0
for fixture in fixtures:
if 'Id' in fixture.keys():
fixtureUpdate = StraightredFixture(fixtureid=fixture['Id'],away_team=fixture['AwayTeam_Id'],home_team=fixture['HomeTeam_Id'])
fixtureUpdate.save()
numberOfFixturesUpdated = numberOfFixturesUpdated + 1
return HttpResponse(str(numberOfFixturesUpdated) + " fixture/s have been added/updated.")
else:
return HttpResponse("You must be logged in to update teams.")
When I try to call it I get the following error:
Cannot assign "'54'": "StraightredFixture.home_team" must be a
"StraightredTeam" instance.
54 id the correct teamid that needs to be entered. 54 is definitely in the teamdid of the straightred_fixture table.
I assume it is something to do with the foreign key as anything that is not a foreign key seems to work perfectly. I am sure I have a simple syntax issue somewhere.
Many thanks for any help that may be give, Alan.

You probably upgraded from some older Django version?
If so, note that now, when assigning foreign keys, you must assign a saved instance of the foreign object. If you want to just assign by id, then use <fieldname>_id
I believe, here,
fixtureUpdate = StraightredFixture(
fixtureid=fixture['Id'],
away_team_id=fixture['AwayTeam_Id'],
home_team_id=fixture['HomeTeam_Id']
)
...should do the trick.

Related

How to join two different modal in django?

I'm using django 3.2. And DB name postgres.
I'm stuck in a problem where i want to combine two modals.
I have following two modals
1- Profiles
2- Ratings foreignKey(Profiles)
now I want to return profiles list with their ratings.
And this is what i'm unable to achieve. Actually I don't know how to do that. I think it can be done by inner join by profile_id but how to do this with django ?
profiles/views.py:
#api_view(['GET'])
#permission_classes([IsAuthenticated])
def profile_list(request):
if request.method=="GET":
kind = kind.lower()
paginator = CustomPagination()
paginator.page_size = 10
print("dat da da da da ==>> ",request.data)
coordinates = request.data["coordinates"]
nearby_count = Profile.objects.nearby_count(coordinates)
total_count = nearby_count
total_page = total_page_counter(nearby_count)
profiles_queryset = Profile.objects.nearby_ground_list(coordinates)
## Rating.objects ????
page_data_of_profiles=None
try:
page_data_of_profiles = paginator.paginate_queryset(profiles_queryset, request)
except:
pass
serializer = ProfileSerializer(page_data_of_profiles, many=True)
return Response({"status":"success","message": "Ok","total_count":total_count,"total_page":total_page, "data": serializer.data},status=status.HTTP_200_OK)
ratings/modals.py
class Rating(models.Model):
user = models.ForeignKey(User, verbose_name=_("user"), on_delete=models.CASCADE,null=True,blank=True)
profile = models.ForeignKey(Profile, verbose_name=_("profile"), on_delete=models.CASCADE)
stars = models.IntegerField(_("stars"),default=0)
is_remove = models.BooleanField(_("is_remove"),default=False)
create_time = models.DateTimeField(_("Create time"), default=timezone.now)
profiles/modals.py
# Create your models here.
class Profile(models.Model):
owner = models.ForeignKey(User, verbose_name=_("Owner"), on_delete=models.CASCADE)
name = models.CharField(_("Name"), max_length=150,null=True)
location = geo_models.PointField(geography=True, default=Point(0.0, 0.0),null=True,blank=True)
is_premium = models.BooleanField(_("premium"), default=False)
is_remove = models.BooleanField(_("Remove"), default=False)
create_time = models.DateTimeField(_("Create time"), default=timezone.now)
users_with_ratings = Rating.objects.all().values("user__name", "stars").distinct("user")

Foreign Keys are not getting assigned - Django

i am new to this, any recommendations are accepted, my main problem is that i have some foreign keys that are getting assigned in my database.
As you can see the last 4 models are related to the patient model through a Foreign Key, these are the fields that are not getting assigned in my project.
Models
class Patient(models.Model):
Codigo = models.CharField(max_length=20,default=None,null=False)
Nombres = models.CharField(max_length=100,null=False)
Apellidos = models.CharField(max_length=100,null=False)
Fecha_Nacimiento = models.DateField()
Numero_Telefonico = models.CharField(max_length=200,default=' ')
Email = models.CharField(max_length=256,unique=True,blank=True,default=' ')
Genero = models.ForeignKey(Gender,on_delete=models.DO_NOTHING,default=None,null=True)
Nacionalidad = models.ForeignKey(Nationality,on_delete=models.DO_NOTHING,default=None,null=True)
Estado_Civil = models.ForeignKey(CivilStatus,on_delete=models.DO_NOTHING,null=True)
Ocupacion = models.CharField(max_length=200)
Lugar_de_Procedencia = models.CharField(max_length=200)
Lugar_de_Residencia = models.CharField(max_length=200)
def __str__(self):
return self.Nombres + ' ' + self.Apellidos
class MedicalInfo(models.Model):
Expediente = models.CharField(max_length=500,blank=True)
Sangre = models.ForeignKey(BloodType,on_delete=models.DO_NOTHING,default=None,null=True)
Peso = models.FloatField()
Estatura = models.FloatField()
Alergia = models.ForeignKey(Allergies,on_delete=models.CASCADE,default=None,null=True)
Observacion = models.CharField(max_length=500,default= ' ',null=True)
Paciente = models.OneToOneField(Patient,on_delete=models.CASCADE,default=None,blank=True,null=True)
class InsuranceInfo(models.Model):
Seguro = models.ForeignKey(InsuranceCompany,on_delete=models.DO_NOTHING, default=None,blank=True,null=True)
Tipo_de_Poliza = models.ForeignKey(Policy,on_delete=models.DO_NOTHING,default=None,blank=True,null=True)
Numero_Poliza = models.IntegerField(default=None,blank=True,null=True)
Vencimiento = models.DateField(default=None,blank=True,null=True)
Paciente = models.OneToOneField(Patient,on_delete=models.CASCADE,default=None,blank=True,null=True)
class Relatives(models.Model):
Parentesco = models.ForeignKey(Family_relation, on_delete=models.DO_NOTHING,default=None,blank=True,null=True)
Nombre = models.CharField(max_length=100,blank=True)
Apellido = models.CharField(max_length=100,blank=True)
Telefono = models.CharField(max_length=100,blank=True)
Correo = models.EmailField(blank=True)
Nacimiento = models.DateField(blank=True,null=True)
Pariente = models.OneToOneField(Patient,on_delete=models.CASCADE,default=None,blank=True,null=True)
def __str__(self):
return self.Nombre + ' ' + self.Apellido
class Background(models.Model):
Padecimiento = models.CharField(max_length=200)
Control = models.CharField(max_length=200)
Medicamento = models.CharField(max_length=500)
Paciente = models.OneToOneField(Patient,on_delete=models.CASCADE,default=None,blank=True,null=True)
These are my forms, you can see that i exluded the 'Paciente' or 'Pariente' field (depending on the name of the model) in some of them because i want to assigned that field a value through a view which i will show you above the forms section.
Forms
class PatientForm(forms.ModelForm):
class Meta:
model = Patient
fields = '__all__'
widgets = {
'Fecha_Nacimiento': DateInput()
}
class RelativesForm(forms.ModelForm):
class Meta:
model = Relatives
exclude = ('Pariente',)
widgets = {
'Nacimiento': DateInput()
}
class MedicalInfoForm(forms.ModelForm):
class Meta:
model = MedicalInfo
exclude = ('Paciente',)
class InsuranceInfoForm(forms.ModelForm):
class Meta:
model = InsuranceInfo
exclude = ('Paciente',)
class BackgroundForm(forms.ModelForm):
class Meta:
model = Background
exclude = ('Paciente',)
This is the view i was talking about, in here i attempted to create a view containing all those forms and show it as one, the 'Patient' i created i this form is the one i want to assign to the field i excluded in the forms, that's why i excluded it because i wanted to assigned it manually, this is my attempt, i don't know what i am doing wrong or is missing. Any recommendations or solutions are accepted. Thanks!
Views
def PatientFormView(request):
if request.method == 'POST':
patientinfo = PatientForm(data=request.POST)
medicalinfo = MedicalInfoForm(data=request.POST)
insuranceinfo = InsuranceInfoForm(data=request.POST)
backgroundinfo = BackgroundForm(data=request.POST)
first_relative = RelativesForm(data=request.POST)
if patientinfo.is_valid() and medicalinfo.is_valid() and backgroundinfo.is_valid() and insuranceinfo.is_valid() and first_relative.is_valid():
patient = patientinfo.save()
patient.save()
medicalinfo.save(commit=False)
medicalinfo.Paciente = patient
medicalinfo.save()
backgroundinfo.save(commit=False)
backgroundinfo.Paciente = patient
backgroundinfo.save()
insuranceinfo.save(commit=False)
insuranceinfo.Paciente = patient
insuranceinfo.save()
first_relative.save(commit=False)
first_relative.Pariente = patient
first_relative.save()
return HttpResponseRedirect(reverse('patients'))
else:
patientinfo = PatientForm()
medicalinfo = MedicalInfoForm()
insuranceinfo = InsuranceInfoForm()
backgroundinfo = BackgroundForm()
first_relative = RelativesForm()
return render(request,'patients/patient_form.html',context={'patientinfo':patientinfo,'backgroundinfo':backgroundinfo,'first_relative':first_relative,'medicalinfo':medicalinfo,'insuranceinfo':insuranceinfo})
You are trying to update form instances. Change them as:
insurance = insuranceinfo.save(commit=False)
insurance.Paciente = patient
insurance.save()
Apply this approach to other models.

Django Cannot Insert ForeignKey into Database : It's Error ,MultiValueDictKeyError

I try to Insert Foreign Key into the database. But When I hit the submit, I get
Error:MultiValueDictKeyError
model.py
from django.db import models
class Candidate_Military(models.Model):
"""docstring forCandidate_Military."""
auto_increment_id = models.AutoField(primary_key=True)
military_status = models.CharField(max_length=100,null=True)
military_reason = models.CharField(max_length=250,null=True)
def __int__(self):
return self.auto_increment_id
class Candidate_Basic(models.Model):
"""docstring for Candidate_basic."""
id_number = models.CharField(primary_key=True,max_length=13)
position = models.CharField(max_length=250)
salary = models.IntegerField()
profile_pic = models.ImageField()
nickname = models.CharField(max_length=100)
name_title = models.CharField(max_length=50)
firstname = models.CharField(max_length=250)
lastname = models.CharField(max_length=250)
candidate_military = models.ForeignKey(Candidate_Military, on_delete=models.CASCADE,null=True)
def __int__(self):
return self.id_number
view.py
from .models import Candidate_Basic, Candidate_Military
def index(request):
template=loader.get_template("index.html")
return HttpResponse(template.render())
def submit_applyjob(request):
print("ohh! It's sumbitted!")
military_status = request.POST.get('military_status')
military_reason = request.POST.get('military_reason')
candidate_military = Candidate_Military(military_status=military_status,military_reason=military_reason)
candidate_military.save()
id_number = request.POST["id_number"]
position = request.POST["position"]
salary = request.POST["salary"]
profile_pic = request.POST["profile_pic"]
nickname = request.POST["nickname"]
name_title = request.POST["name_title"]
firstname = request.POST["firstname"]
lastname = request.POST["lastname"]
print("candidate_military" + "-->>>" + str(candidate_military))
candidate_military = request.POST["candidate_military"]
candidate_basic = Candidate_Basic(id_number=id_number,position=position,salary=salary,
profile_pic=profile_pic,nickname=nickname,name_title=name_title,
firstname=firstname,lastname=lastname,candidate_military=candidate_military)
candidate_basic.save()
return render(request, "index.html")
And When I fill the form and hit the submit button It's Error Like This
I don't Understand Why It cannot insert into my database. I try to print the value of 'candidate_military' It's Print the right value!
Plz Help me to Debug This issue T^T
I try to fix this code with
candidate_military = request.POST.get("candidate_military",False)
But It's not Work ;
ValueError: Cannot assign "False": "Candidate_Basic.candidate_military" must be a "Candidate_Military" instance.
The issue is in this line
candidate_military = request.POST["candidate_military"]
There is no need for this line. Just remove it and the code should just work fine.

Django order_by not working properly

I'm trying to get all the conversations ordered by it last message, but when I use the order_by clausule, the conversations are repeated.
Query without order_by:
conversaciones = Conversacion.objects.filter(usuarios=request.user)
Result (Grouped by Conversations but not ordered by the most recent last message first):
Query with order_by:
conversaciones = Conversacion.objects.filter(usuarios=request.user).order_by('-mensaje__fechaEnvio')
Result:
My models.py:
class Mensaje(models.Model):
remitente = models.ForeignKey('Usuario', on_delete=models.CASCADE, related_name='remitente')
destinatario = models.ForeignKey('Usuario', on_delete=models.CASCADE, related_name='destinatario')
cuerpo = models.TextField(validators=[MaxLengthValidator(750)])
leido = models.BooleanField(default=False)
fechaEnvio = models.DateTimeField(auto_now_add=True)
conversacion = models.ForeignKey('Conversacion', on_delete=models.CASCADE)
class Meta:
ordering = ['-fechaEnvio']
def __str__(self):
return str(self.remitente) + ' -> ' + str(self.destinatario)
class Conversacion(models.Model):
usuarios = models.ManyToManyField('Usuario', related_name='usuarios')
agresion = models.ForeignKey('Agresion', on_delete=models.CASCADE)
#property
def ultimoMensaje(self):
return self.mensaje_set.latest('fechaEnvio')
I found a solution:
conversaciones = Conversacion.objects.filter(usuarios=request.user).annotate(max_fecha=Max('mensaje__fechaEnvio')).order_by('-max_fecha')
I'm using MySQL so I can't use distinct with params.
As #jota suggested, I can add something in your model Mesanje. Make ordering a tuple and don't forget to add a comma and don't forget to make migrations again.
class Mesanje(models.Model):
........
class Meta:
ordering = ('-fechaEnvio',)

Django: Adding more fields to each ManyToMany Field option

Is It possible to add one or more Char Fields to each ManyToMany field option?
My Models:
class engineeringUni(models.Model):
field2 = models.CharField(max_length=200)
des_eng = models.CharField(max_length=1000, default='Add description')
def __str__(self):
return self.field2
def description_eng_universities(self):
return self.des_eng
class engineering_courses(models.Model):
course_name = models.CharField(max_length=400)
course_description = models.CharField(max_length=1000, default='This is a description')
course_offered_by = models.ManyToManyField(engineeringUni, related_name='course_offered_by')
course_duration = models.IntegerField(blank=False, default='2')
def __str__(self):
return self.course_name
def description_course(self):
return self.course_description
def offered_by_courses(self):
return self.course_offered_by
def duration_courses(self):
return str(self.course_duration)
As you can see in the image, I have the options in the ManyToMany field. Those options are:
University 1
University 2
University 3
What I want to have is an additional text (Char) field next to each of these options (University 1, University 2, University 3).
Is this possible?
EDIT 1:
Current code:
class engineering_courses(models.Model):
course_name = models.CharField(max_length=400)
course_description = models.CharField(max_length=1000, default='This is a description')
course_offered_by = models.ManyToManyField(
engineeringUni,
through='ThroughModel',
through_fields=('course', 'university'),
)
course_duration = models.IntegerField(blank=False, default='2')
def __str__(self):
return self.course_name
def description_course(self):
return self.course_description
def offered_by_courses(self):
return self.course_offered_by
def duration_courses(self):
return str(self.course_duration)
class ThroughModel(models.Model):
course = models.ForeignKey(engineering_courses, on_delete=models.CASCADE)
university = models.ForeignKey(engineeringUni, on_delete=models.CASCADE)
additional_text = models.CharField(max_length=200)
EDIT 2: Problem fixed. I was getting that no table error because I had deleted the migration files and on deleting database (db.sqlite3) file and applying migration again, It fixed.
You can use a through model in the ManyToManyField (docs). This model can be used to store any additional fields.
class engineering_courses(models.Model):
# ...
course_offered_by = models.ManyToManyField(engineeringUni, related_name='course_offered_by', through='ThroughModel')
class ThroughModel(models.Model):
course = models.ForeignKey(engineering_courses)
university = models.ForeignKey(engineeringUni)
additional_text = models.CharField()
Take another look at the django docs referenced in the answer from arjun27. You have more than one foreign key in your ThroughModel, so django is confused. Try specifying the through fields in your engineering_course model, migrate the changes, and see if that works.
Mark

Categories

Resources