Foreign Keys are not getting assigned - Django - python

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.

Related

Django REST: Set all Serializer fields as not required at once

Is there any way to set my serializer fields as not required by default? it'll take me hours to set every field of every serializer I have as not required so I wanted to know if there's any shortcut.
One example:
class ComputersSerializer(serializers.ModelSerializer):
name = serializers.CharField(required=False)
serial = serializers.CharField(required=False)
otherserial = serializers.CharField(required=False)
contact = serializers.CharField(required=False)
contact_num = serializers.CharField(required=False)
comment = serializers.CharField(required=False)
date_mod = serializers.DateTimeField(required=False)
is_template = serializers.IntegerField(default=0)
template_name = serializers.CharField(required=False)
is_deleted = serializers.IntegerField(default=0)
is_dynamic = serializers.IntegerField(default=0)
ticket_tco = serializers.DecimalField(max_digits=20, decimal_places=4, required=False)
uuid = serializers.CharField(required=False)
date_creation = serializers.DateTimeField(required=False)
is_recursive = serializers.IntegerField(default=0)
last_inventory_update = serializers.DateTimeField(required=False)
computertypes = ComputertypesSerializer(required=False)
computermodels = ComputermodelsSerializer(required=False)
entities = EntitiesSerializer(required=False)
networks = NetworksSerializer(required=False)
locations = LocationsSerializer(required=False)
autoupdatesystems = AutoupdatesystemsSerializer(required=False)
users = assistanceSerializers.UsersSerializer(required=False)
groups = assistanceSerializers.GroupsSerializer(required=False)
states = StatesSerializer(required=False)
users_tech = assistanceSerializers.UsersSerializer(required=False)
groups_tech = assistanceSerializers.GroupsSerializer(required=False)
manufacturers = ManufacturersSerializer(required=False)
class Meta:
model = Computers
fields = '__all__'
For the moment I had to set it for each field. I've been searching if someone had the same problem but it looks like I'm lazier than the rest of programmers.
If you want to make the field optional, it should be defined in your model.
The ModelSerializer will react to that.
From the docs:
If you're using Model Serializer default value will be False if you have specified blank=True or default or null=True at your field in your Model.
Try this:
class ComputersSerializer(serializers.ModelSerializer):
class Meta:
model = Computers
fields = '__all__'
extra_kwargs = {field.name:{'required': False} for field in Computers._meta.get_fields()}

Django write a get_form() function

I have an app that creates modelForms dynamically based on models. These forms must be dynamically loaded on the template.
I need to write a function in my view that gets all the forms from forms.py or gets a specific form by it's name. Something similar to get_models(appName) and get_model(AppName, modelName) but for forms instead of models.
How can I write it and where should I write it?
in Registery or in forms or somewhere else?
Here is my code:
Models.py
class PrimaryInfo(models.Model):
Name = models.CharField(max_length=200, blank=False, null=True) #required. Must be filled by user
Surname = models.CharField(max_length=200, blank=False, null=True)
DateOfBirth = models.DateField('date of birth', blank=False, null=True)
<Some Other fields>
...
def calculateAge(self):
if not self.DateOfBirth is None:
thisYear = timezone.now().date().year
return thisYear - self.DateOfBirth.year
pass
<some other functions>
...
#Here come all the related tables
class Jobs(models.Model):
Rel = models.ForeignKey(PrimaryInfo, on_delete=models.CASCADE)
Job = models.CharField(max_length=200)
Age = models.IntegerField(default=0)
Country = models.CharField(max_length=200)
def __str__(self):
return self.Job
<some other related models>
....
My View:
def detail(request, personId):
appName = urls.app_name
tablesPrefix = appName + '_'
person = PrimaryInfo.objects.get(pk = personId)
peopledbModels = apps.get_models(appName)
fieldsList = []
relatedModels = []
relationshipsDic = {}
formsFileName = "write.py"
parentModelForms = []
# identify which models are parent and which ones are relationships. makes a dictionary (Of string, list) for the results.
for m in peopledbModels:
if m._meta.db_table.startswith(appName):
fields = m._meta.get_fields()
for fld in fields:
if fld.is_relation:
if fld.many_to_one or fld.many_to_many or fld.one_to_one:
pass
else:
relatedModels.append(fld.name)
relationshipsDic["{}".format(m._meta.label).replace("{}.".format(appName),"")] = relatedModels
#Write the modelForm from parent model into forms.py
for pmdl in relationshipsDic.keys():
parentModelName = pmdl
modelFormExist = False
with open("{}{}/{}".format(djangoSettings.MEDIA_ROOT, appName, formsFileName)) as file:
if "class {}Form(forms.ModelForm):".format(parentModelName) in file.read():
file.close()
modelFormExist = True
if modelFormExist == False:
with open("{}{}/{}".format(djangoSettings.MEDIA_ROOT, appName, formsFileName), "a+") as file:
file.write("\n\nclass {0}Form(forms.ModelForm):\n\tclass Meta:\n\t\tmodel = {0}\n\t\tfields = '__all__'".format(parentModelName))
file.close()
parentModel = apps.get_model(appName, pmdl)
instance = get_object_or_404(parentModel, pk=personId)
parentModelForm = "{}Form".format(pmdl) #this is where I need to get the form object with a variable name from forms.py
parentModelForm = parentModelForm(instance = instance) #this is not working (string object is not callable)
parentModelForms.append(parentModelForm)
<then pass this list of models to the template>
...
My forms (automatically populated from my view):
class PrimaryInfoForm(forms.ModelForm):
class Meta:
model = PrimaryInfo
fields = '__all__'
class JobsForm(forms.ModelForm):
class Meta:
model = Jobs
fields = '__all__'

AssertionError: The field '' was declared on serializer '' but has not been included in the 'fields' option. optional

Im, using Django Rest Framework to make an APIRest but I got this error when trying to make a simple crud for the discount resource
This is my model
class Discount(BaseModel):
""" Discount Model. """
code = models.CharField(max_length=50)
rate = models.DecimalField( max_digits=3, decimal_places=2)
class DiscountStatus(models.TextChoices):
ENABLED = 'ENABLED'
DISABLED = 'DISABLED'
REDEEMED = 'REDEEMED'
status = models.CharField("status", choices=DiscountStatus.choices, default=DiscountStatus.ENABLED, max_length=10)
insurance_company = models.ForeignKey("sanitas.InsuranceCompany", on_delete=models.CASCADE)
appointment = models.ForeignKey("sanitas.Appointment", verbose_name="appointment", on_delete=models.CASCADE, blank=True, null=True)
class Meta():
""" Meta class. """
db_table = 'discounts'
This is my serializer
class DiscountModelSerializer(serializers.ModelSerializer):
""" Insurance company model serializer. """
insurance_company = InsuranceCompanyModelSerializer(many=False, read_only=True, allow_null=True, required=False)
insurance_company_id = serializers.IntegerField(allow_null=True, required=False,)
appointment = AppointmentModelSerializer(many=False, read_only=True, allow_null=True, required=False)
appointment_id = serializers.IntegerField(allow_null=True, required=False)
class Meta():
""" Meta class. """
model = Discount
fields = (
'id',
'code',
'rate',
'status',
'appointment'
'insurance_company'
'insurance_company_id'
'appointment_id'
)
And this is my Viewset
class DiscountViewset(viewsets.ModelViewSet):
""" Schedule items will be the time unit to manage appointments. """
queryset = Discount.objects.all()
serializer_class = DiscountModelSerializer
#action(methods=['post'], detail=False)
def generate(self, request):
""" Create dicounts in bulk. """
rate = 1 - request.data['rate'] / 100
insurance_company = get_object_or_404(InsuranceCompany, pk=request.data['insurance_company_id'])
count = 0
amount = request.data['amount']
response = []
while count < amount:
code = insurance_company.code + randomString(8)
discount = Discount()
discount.rate = rate
discount.code = code
discount.insurance_company = insurance_company
discount.save()
serializer = DiscountModelSerializer(discount)
response.append(serializer.data)
count = count + 1
return Response(response, status=status.HTTP_200_OK)
My guess is that the error appears because I have an optional field (is not really optional, but when I create the discount codes there is no appointment yet so it will be added later) and the error appears because I didn't add the field "appointment" and when trying to retrieve the resources I make It shows this error
AssertionError at /discounts/generate/ The field 'appointment_id' was declared on serializer DiscountModelSerializer, but has not been included in the 'fields' option.

Django: 'ModelForm' object has no attribute

I'm working with Django Forms in order to create a new object, but I'm having problems with it. It all renders OK, but when I submit the Form, an error is raised:
"AttributeError at /rutinas/nueva_rutina
'DiaForm' object has no attribute 'ejercicios'"
I've tried many possible solutions I read here, but they didn't work. I think the problem is with the M2M relationship, but it can also be for processing two forms at a time. Here are my files
models.py
class Ejercicio(models.Model):
id = models.AutoField(primary_key=True)
nombre = models.CharField(max_length=30, default='')
descripcion = models.TextField(default='')
gif = models.ImageField(default='')
def __str__(self):
return self.nombre
class Rutina(models.Model):
id = models.AutoField(primary_key=True)
nombre = models.CharField(max_length=30, default='')
def __str__(self):
return self.nombre
class Dia(models.Model):
ejercicios = models.ManyToManyField(Ejercicio)
rutina = models.ForeignKey(Rutina, on_delete=models.CASCADE)
forms.py
class RutinaForm(forms.ModelForm):
class Meta:
model = Rutina
fields = '__all__'
labels = {
'nombre': _('Nombre')
}
class DiaForm(forms.ModelForm):
ejercicios = forms.ModelMultipleChoiceField(queryset=Ejercicio.objects.all())
class Meta:
model = Dia
fields = ['ejercicios']
labels = {
'ejercicios': _('Ejercicios')
}
views.py
def nueva_rutina_view(request):
if request.method == "POST":
form = RutinaForm(request.POST)
dia_form_1 = DiaForm(request.POST)
dia_form_2 = DiaForm(request.POST)
dia_form_3 = DiaForm(request.POST)
if form.is_valid() and dia_form_1.is_valid() and dia_form_2.is_valid() and dia_form_3.is_valid():
rutina = form.save(commit=False)
dia1 = dia_form_1.save(commit=False)
dia2 = dia_form_2.save(commit=False)
dia3 = dia_form_3.save(commit=False)
rutina.save()
dia1.rutina = rutina
dia2.rutina = rutina
dia3.rutina = rutina
dia1.ejercicios = dia_form_1.ejercicios
dia2.ejercicios = dia_form_2.ejercicios
dia3.ejercicios = dia_form_3.ejercicios
dia1.save()
dia2.save()
dia3.save()
return redirect(historial_rutinas_view)
else:
form = RutinaForm()
dia_form_1 = DiaForm()
dia_form_2 = DiaForm()
dia_form_3 = DiaForm()
return render(request, 'rutinas/nueva-rutina.html', {'form': form, 'dia_form_1': dia_form_1, 'dia_form_2': dia_form_2, 'dia_form_3': dia_form_3})

Django update MySQL database issue involving foreign keys

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.

Categories

Resources