Create a data migration with a overwrote ,save() method model - django

I am trying to upload some testing data to an app, using the option of the migrations.All the data is storaged in a .Yaml file in the app ans I have some other migrations that runs perfectly uploading all the data.
But this one has a problem. In this model (Transactions) I created 3 self-writen, fields that are calculated when calling to the save() method. This process run perfectly when I sent the data through the View. But when I send it through the migration, fails as if the save method is not overwritten. I don't know what to do to accomplish the upload as a migration.
The migration
from django.db import migrations
from django.core import serializers
def transactions(apps, schema_editor):
with open('fixtures/transactions.yaml') as trans:
for obj in serializers.deserialize("yaml", trans):
t=apps.get_model("acounts", "Transactions")()
cat=apps.get_model("acounts","Category")
.objects.get(pk=obj.object.category.pk)
cuen=apps.get_model("acounts", "Acount").objects.get(pk=obj.object.acount.pk)
print(obj)
t.tipo=obj.object.tipo
t.description=obj.object.description
t.monto=obj.object.monto
t.date=obj.object.date
# t.category=obj.object.category
t.category=cat
# t.acount=obj.object.acount
t.acount=cuen
t.save()
class Migration(migrations.Migration):
dependencies = [
('acounts', '0002_populate_acounts'),
]
operations = [
(migrations.RunPython(transactions))
]
The Model
class Transactions(models.Model):
TYPE_CHOICES = (
('GASTO', 'Gasto'),
('INGRESO', 'Ingreso'),
)
tipo = models.CharField(
choices=TYPE_CHOICES,
max_length=20
)
description=models.CharField(max_length=100)
monto=models.DecimalField(max_digits=25,
decimal_places=2,
null=False)
category=models.ForeignKey('Category',
on_delete=models.CASCADE,
null=False)
acount=models.ForeignKey('Acount',
on_delete=models.CASCADE,
null=False)
date=models.DateField()
total_USD=models.DecimalField(
max_digits=25,
decimal_places=2,
editable=False);
total_BTC=models.DecimalField(
max_digits=25,
decimal_places=9,
editable=False);
total_BSS=models.DecimalField(
max_digits=25,
decimal_places=2,
editable=False);
total_EUR=models.DecimalField(
max_digits=25,
decimal_places=2,
editable=False);
created_at=models.DateTimeField(
auto_now_add=True,
editable=False)
updated_at=models.DateTimeField(
auto_now=True,
editable=False)
def save(self):
cotizations=Currency.objects.all()
currency=self.acount.currency.name
in_usd=self.monto/Currency.objects.get(name=currency).price_USD_now
query_btc=in_usd*Currency.objects.get(name='BTC').price_USD_now
query_bss=in_usd*Currency.objects.get(name='YEN').price_USD_now
query_eur=in_usd*Currency.objects.get(name='EUR').price_USD_now
self.total_USD=in_usd
self.total_BTC=query_btc
self.total_YEN=query_bss
self.total_EUR=query_eur
super(Transactions, self).save()
return query_btc;
The Error
raise utils.IntegrityError(*tuple(e.args))
django.db.utils.IntegrityError: (1048, "Column 'total_USD' cannot be null
The same method runs perfect when done trough the view, How could I create a data migration for this model using the overwritten .save() method?

Related

Django Rest Framework not validating all model's fields

I searched for this problem everywhere without being able to find an answer though it seems basic DRF usage, so I might be missing sth.
I have a Customer model with certain required fields:
from django.db import models
from django.utils.translation import gettext_lazy as _
from applications.core.models.country import Country
from applications.core.models.customer_states.customer_state import \
CustomerState
class Customer(models.Model):
class Meta:
verbose_name = _('customer')
verbose_name_plural = _('customers')
user_email = models.EmailField(_('email'), max_length=100, unique=True, default=None)
complete_name = models.CharField(_('complete name'), max_length=200, default=None)
phone = models.CharField(_('phone'), max_length=50, default=None)
country = models.ForeignKey(Country, models.PROTECT, verbose_name=_('country'), default=None)
city = models.CharField(_('city'), max_length=100, default=None)
city_state = models.CharField(_('city state'), max_length=100, default=None)
address = models.CharField(_('address'), max_length=100)
zip_code = models.CharField(_('zip code'), max_length=50, default=None)
customer_state = models.OneToOneField(CustomerState, models.PROTECT)
notes = models.TextField(_('notes'), max_length=200, blank=True, null=True)
And I have this serializer:
from rest_framework import serializers
from applications.core.models.customer import Customer
from applications.core.models.customer_states.implementations.pending_manual_validation_state import \
PendingManualValidationState
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
def to_internal_value(self, data):
self.add_default_state_if_missing(data)
return super(CustomerSerializer, self).to_internal_value(data)
#staticmethod
def add_default_state_if_missing(data):
data['customer_state'] = PendingManualValidationState.objects.create().pk
Though I have explicitly told DRF that it should use all model's fields it does not seem to check for the requirement of fields like 'address' and whenever I create the serializer with data missing 'address' and call serializer.is_valid() it returns True.
Why?
Found the answer by myself:
It would seem that default=None in the field makes DRF realize that even if the field is required, not receiving data for it is not a problem.
I set those default because otherwise Django would set a '' default value and thus, PostgreSQL would not raise exceptions for those empty data fields. But now that I am starting to use DRF for validations I no longer need those default.
Yet, if I happen to create and save a Customer without using the serializer, then I risk letting Django create a field with a default '' without having PostgreSQL complain about it. I figure that risk has a low probability though.

Attribute Error in Django model Foreign Key

In My Django Project, there are two apps: Login and Company
The error that am receiving in this is
AttributeError: module 'login.models' has no attribute 'Country'
Company App > models.py
from django.db import models
from login import models as LM
class CompanyProfile(models.Model):
full_name = models.CharField(max_length=255,
unique = True)
country = models.ForeignKey(LM.Country,
on_delete=models.SET_NULL,
null=True,
blank=False)
state = models.ForeignKey(LM.State,
on_delete=models.SET_NULL,
null=True,
blank=False)
def __str__(self):
return self.full_name
Login App > models.py
class Country(models.Model):
"""List of Country"""
name = models.CharField(max_length=50, unique= True, default='None')
code = models.CharField(max_length=2, unique= True, primary_key=True, default ='NA')
def __str__(self):
return str(self.code)
class State(models.Model):
"""List fo State"""
region = models.CharField(max_length = 255, unique = True, primary_key=True, default='None')
country = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True, blank=False, default ='NA')
def __str__(self):
return self.region
Here is test to check that weather is login is getting imported or not
def test_import():
try:
# import pdb; pdb.set_trace()
importlib.find_loader('LM.Country')
found = True
except ImportError:
found = False
print(found)
Answer is received stands to be True
python3 manage.py shell
>>> test_import()
True
Now on other stackoverflow blogs i checked i thought it could be of Circlular Import
But i have already fixed that still am getting this error?
Thanks in Advance
Regards
I am not able to see any issue here technically. Maybe Django doesn't support this alias way of mentioning model as Foreign Key which I have never tried this way.
But I would suggest to use string format for adding Foreign Key of other model as below.
class CompanyProfile(models.Model):
full_name = models.CharField(max_length=255, unique = True)
# In following line, as I mention model name in string which django understands
country = models.ForeignKey('login.Country', on_delete=models.SET_NULL,
null=True,blank=False)
Another way is simple import but it might be a problem in case of circular depedencies. So I don't recommend to use that.
I hope you get the answer out of it.

after I created multiple models in my django app for the restframwork I start getting more errs

I created a single model django project then I added tow more models then I got this err
RecursionError at /elements/
maximum recursion depth exceeded while calling a Python object
then I reinstalled some packages like djangorestframwork-recursion, then I got this err
Error at /
Incorrect padding
Request Method: GET
Request URL: http://127.0.0.1:8000/
Django Version: 3.0.8
Exception Type: Error
Exception Value:
Incorrect padding
Exception Location: //anaconda3/lib/python3.7/base64.py in b64decode, line 87
Python Executable: //anaconda3/bin/python
Python Version: 3.7.3
Python Path:
['/Users/apple/Desktop/Trying to clone notionso note taking app with django '
'and reac1/backend/restapi',
'//anaconda3/lib/python37.zip',
'//anaconda3/lib/python3.7',
'//anaconda3/lib/python3.7/lib-dynload',
'/Users/apple/.local/lib/python3.7/site-packages',
'//anaconda3/lib/python3.7/site-packages',
'//anaconda3/lib/python3.7/site-packages/aeosa']
Server time: Fri, 7 Aug 2020 06:59:57 +0000
also when I ran python manage.py makemigrations i got
You are trying to change the nullable field 'text' on components to non-nullable without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)
3) Quit, and let me add a default in models.py
Select an option:
what is the problem with the nullable field 'text' (also I change every null=Flase to null=True i got the same err.
models.py
# this is a recursive model
from django.db import models
class elements(models.Model):
tag = models.CharField(blank=True, null=True, max_length=20)
text = models.TextField(blank=True, null=False)
src = models.URLField(blank=True, null=True)
# problem: styles replace spaces with slashes (/)
# I tried: json field but did'nt work.
style = models.TextField(blank=True, null=True)
main = models.ForeignKey(
'self', null=True, blank=True, related_name="sub", on_delete=models.PROTECT)
class styles(models.Model):
name = models.TextField(blank=True, null=True, max_length=50)
style = models.TextField(blank=True, null=True)
main = models.ForeignKey(
'self', null=True, blank=True, related_name="sub", on_delete=models.PROTECT)
class components(models.Model):
name = models.TextField(blank=True, null=True, max_length=50)
tag = models.CharField(blank=True, null=True, max_length=20)
text = models.TextField(blank=True, null=False)
src = models.URLField(blank=True, null=True)
style = models.TextField(blank=True, null=True)
main = models.ForeignKey(
'self', null=True, blank=True, related_name="sub", on_delete=models.PROTECT)
serialzers.py
from rest_framework import serializers
from models.models import elements, styles, components
from rest_framework_recursive.fields import RecursiveField
class elementsSerializer(serializers.ModelSerializer):
sub = RecursiveField(many=True, required=False)
class Meta:
model = elements
fields = ('id', 'tag', 'text', 'src', 'style', 'main', 'sub')
class stylesSerializer(serializers.ModelSerializer):
sub = RecursiveField(many=True, required=False)
class Meta:
model = styles
fields = ('id', 'name', 'style', 'main', 'sub')
class componentsSerializer(serializers.ModelSerializer):
sub = RecursiveField(many=True, required=False)
class Meta:
model = components
fields = ('id', 'name', 'tag', 'text', 'src', 'style', 'main', 'sub')
view.py
from models.models import elements, styles, components
from .serializers import elementsSerializer, stylesSerializer, componentsSerializer
from rest_framework import viewsets
class elementsVeiwSet(viewsets.ModelViewSet):
serializer_class = elementsSerializer
queryset = elements.objects.all()
class stylesVeiwSet(viewsets.ModelViewSet):
serializer_class = stylesSerializer
queryset = styles.objects.all()
class componentsVeiwSet(viewsets.ModelViewSet):
serializer_class = componentsSerializer
queryset = components.objects.all()
urls.py
from models.models import elements, styles, components
from .serializers import elementsSerializer, stylesSerializer, componentsSerializer
from rest_framework import viewsets
class elementsVeiwSet(viewsets.ModelViewSet):
serializer_class = elementsSerializer
queryset = elements.objects.all()
class stylesVeiwSet(viewsets.ModelViewSet):
serializer_class = stylesSerializer
queryset = styles.objects.all()
class componentsVeiwSet(viewsets.ModelViewSet):
serializer_class = componentsSerializer
queryset = components.objects.all()
1)
I am not sure why you have this field in each of your models
main = models.ForeignKey('self', null=True, blank=True, related_name="sub", on_delete=models.PROTECT)
I think this is the reason for your recursion problem. Try removing it.
2) Regarding your problem with the nullable Field text it is because you did not provide a default value (you have to do that because you did not allow it to be Null). You do it like that:
text = models.TextField(blank=True, null=False, default='')

Django Add new record error duplicate key value violates unique constraint "" Django Id doesn't sync with database

I developed a Django Application and it was working correctly, until I did a data migration to the database created by django migration, I migrated the data using an sql script and Pgadmin.
Now I have the database full with records but when I am trying to add new record using django form I got the below error:
duplicate key value violates unique constraint > "learningcenters_partnerorganization_pkey"
DETAIL: Key (id)=(1) already exists.
taking into consideration that the available id for this table is 10.
Model:
class SLPAcademicRound(models.Model):
name = models.CharField(max_length=45,
unique=True,
verbose_name=_('Academic Round Name'))
code = models.CharField(max_length=5,
unique=True,
verbose_name=_('Code'))
cycle = models.ForeignKey(
SLPCycle,
blank=False, null=True,
verbose_name=_('SLP Cycle/SLP Cycle'),
on_delete=models.CASCADE,
)
learning_center = models.ForeignKey(
LearningCenter,
blank=False, null=True,
verbose_name=_('Learning Center'),
on_delete=models.CASCADE,
)
round_date_start = models.DateField(
blank=True,
null=True,
verbose_name=_('SLP Round Start Date')
)
round_date_end = models.DateField(
blank=True,
null=True,
verbose_name=_('SLP Round End Date')
)
current_round = models.BooleanField(
blank=True,
null=True,
verbose_name=_('Current Round')
)
View:
class AddSLPAcademicRoundView(LoginRequiredMixin,
GroupRequiredMixin,
CreateView):
template_name = 'bootstrap4/common_form.html'
form_class = SLPAcademicRoundForm
queryset= SLPAcademicRound.objects.all()
group_required = ["LearningCenterManager"]
def get_absolute_url(self):
return reverse("slp:slp_academic_round_list")
def form_valid(self, form):
print((form.cleaned_data))
form.save(self.request)
return super(AddSLPAcademicRoundView, self).form_valid(form)
def get_form_kwargs(self, *args, **kwargs):
kwargs = super().get_form_kwargs(*args, **kwargs)
kwargs['user'] = self.request.user
return kwargs
I found the solution by pg_get_serial_sequence can be used to avoid any incorrect assumptions about the sequence. This resets the sequence in one shot:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), (SELECT MAX(id) FROM table_name)+1);
Run the command
manage.py sqlsequencereset
This will give you a script to reset the table ids to normal.
Thereafter, run the script in psql and all the table's sequences will be reset.

Django: command management call from model, from view or from where?

I am new on Python3 and DJango.
I am writing an app where the user can register a Company using Company Name and AWS Access Key and Secret Key.
I will use the Access and Secret key to make a inventory "Discovery" of the AWS Account.
Well, I want what every time an user register a company (click to create) django executes a management command called infra_discovery.py inside my app_folder/management/commands (that is working fine when I call via python manage.py infra_discovery).
I have the following model:
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User
from empresa.models import Empresa
class InfraDiscovery(models.Model):
# user will fill this three fiels:
infra_empresa = models.ForeignKey('empresa.Empresa', on_delete=models.CASCADE, blank=True, null=True )
infra_aws_key = models.CharField(max_length=100, null=True, blank=True)
infra_aws_secret = models.CharField(max_length=255, null=True, blank=True)
# my script called infra_discovery have to fill this fields:
infra_vpc = models.TextField(blank=True, null=True )
infra_ec2 = models.TextField(blank=True, null=True )
infra_ebs = models.TextField(blank=True, null=True )
infra_rds = models.TextField(blank=True, null=True )
infra_vpn = models.TextField(blank=True, null=True )
infra_bill = models.TextField(blank=True, null=True )
def __str__(self):
return self.id
def get_absolute_url(self):
return reverse('infrastructure_discovery_edit', kwargs={'pk': self.pk})
I really don't know how to make django fulfill this fields using my script at every time user clicks in "create" button;
What are your suggestion to me?