I have been trying to use with the a legacy database. I have created models file using inscpectdb but now I am not able to perform joins on the table.
I have two tables job_info and username_userid.
Here is my models.class file:
class UseridUsername(models.Model):
userid = models.IntegerField(blank=True, null=True)
username = models.CharField(max_length=100, blank=True, null=True)
class Meta:
managed = False
db_table = 'userid_username'
class LinuxJobTable(models.Model):
job_db_inx = models.AutoField(primary_key=True)
mod_time = models.IntegerField()
account = models.TextField(blank=True, null=True)
exit_code = models.IntegerField()
job_name = models.TextField()
id_job = models.IntegerField()
id_user = models.IntegerField()
class Meta:
managed = False
db_table = 'linux_job_table'
Heren is my serializable class :
class UseridUsernameSerializer(serializers.ModelSerializer):
class Meta:
model = UseridUsername
fields = ('userid','username')
class UserSerializer(serializers.ModelSerializer):
class Meta:
username = UseridUsernameSerializer(many=False)
model = LinuxJobTable
fields = ('account','mod_time','username')
Related
I am trying to POST a new User in User table and assign attribute to this user in the next related table UserAttribute. UserAttribute table contains 'user' field, which is foreign key to the User table.
User.id = UserAttribute.user
My POST method creates a new record in User table, hovewer I can not create relation in UserAttribute table. I am getting:
save() prohibited to prevent data loss due to unsaved related object 'user'.
It is strange because the User is successfully created in User table.
I tried to save record in two ways. You can find the code on belove.
What is more, I tried transactions too.
models.py
class User(models.Model):
id = models.IntegerField(primary_key = True)
email = models.CharField(unique=True, max_length=180)
roles = models.JSONField(default=dict)
password = models.CharField(max_length=255, blank=True, null=True)
name = models.CharField(max_length=255, blank=True, null=True)
firebase_id = models.CharField(max_length=255, blank=True, null=True)
created_at = models.DateTimeField(default=now)
progress_sub_step = models.IntegerField(blank=True, null=True)
step_available_date = models.DateTimeField(blank=True, null=True)
progress_step = models.IntegerField(blank=True, null=True)
active = models.IntegerField(default=1)
last_login_at = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'user'
class Attribute(models.Model):
name = models.CharField(max_length=255)
value = models.CharField(max_length=255)
class Meta:
managed = False
db_table = 'attribute'
class UserAttribute(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name = 'attribute')
attribute = models.ForeignKey(Attribute, on_delete=models.CASCADE)
class Meta:
managed = False
db_table = 'user_attribute'
serializers.py
class UserAttributeSerializer(serializers.ModelSerializer):
class Meta:
model = UserAttribute
fields = ('attribute',)
class UserSerializer(serializers.ModelSerializer):
attribute = UserAttributeSerializer(many = True)
class Meta:
model = User
fields = ('email', 'name', 'firebase_id', 'attribute')
#transaction.atomic()
def create(self, validated_data):
attributes = validated_data["attribute"]
del validated_data["attribute"]
firebase_id_v = validated_data.get('firebase_id')
user_save = User.objects.create(**validated_data)
# Second method
# user_save = User(**validated_data)
# user_save.save()
for attribute in attributes:
a = UserAttribute.objects.create(user = user_save, **attribute)
return user
views.py
class UserAttViewSet(viewsets.ModelViewSet):
queryset = UserAttribute.objects.all()
serializer_class = UserAttributeSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
I have 4 related models and I need to implement the functionality to consistently create instances of these models in a database in one post query. For this I use override of the APIView class post method.
models
class VendorContacts(models.Model):
contact_id = models.AutoField(primary_key=True)
vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE)
contact_name = models.CharField(max_length=45, blank=True)
phone = models.CharField(max_length=45, blank=True)
email = models.CharField(max_length=80, blank=True, unique=True)
class Meta:
db_table = 'vendor_contacts'
class VendorModuleNames(models.Model):
vendor = models.OneToOneField('Vendors', on_delete=models.CASCADE, primary_key=True)
module = models.ForeignKey(Modules, models.DO_NOTHING)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'vendor_module_names'
unique_together = (('vendor', 'module'),)
class Vendors(models.Model):
COUNTRY_CHOICES = tuple(COUNTRIES)
vendorid = models.AutoField(primary_key=True)
vendor_name = models.CharField(max_length=45, unique=True)
country = models.CharField(max_length=45, choices=COUNTRY_CHOICES)
nda = models.DateField(blank=True, null=True)
user_id = models.ForeignKey('c_users.CustomUser', on_delete=models.PROTECT)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'vendors'
unique_together = (('vendorid', 'timestamp'),)
class Modules(models.Model):
MODULES_NAME =tuple(MODULES)
mid = models.AutoField(primary_key=True)
module_name = models.CharField(max_length=50, choices=MODULES_NAME)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'modules'
unique_together = (('mid', 'timestamp'),)
serializer.py
class VendorsSerializer(serializers.ModelSerializer):
class Meta:
model = Vendors
fields = ('vendor_name',
'country',
'nda',)
class VendorContactSerializer(serializers.ModelSerializer):
class Meta:
model = VendorContacts
fields = (
'contact_name',
'phone',
'email',)
class VendorModulSerializer(serializers.ModelSerializer):
class Meta:
model = VendorModuleNames
fields = ('module',)
class ModulesSerializer(serializers.ModelSerializer):
class Meta:
model = Modules
fields = ('module_name', )
views.py
class VendorsCreateView(APIView):
"""Create new vendor instances from form"""
def post(self, request, *args, **kwargs):
vendor_serializer = VendorsSerializer(data=request.data)
vendor_contact_serializer = VendorContactSerializer(data=request.data)
vendor_modules_serializer = VendorModulSerializer(data=request.data)
module_serializer = ModulesSerializer(data=request.data)
try:
vendor_serializer.is_valid(raise_exception=True) \
and vendor_contact_serializer.is_valid(raise_exception=True) \
and vendor_modules_serializer.is_valid(raise_exception=True) \
and module_serializer.is_valid(raise_exception=True)
vendor_serializer.save(user_id=request.user)
# ....
# Some new logic here ????
# ...
except ValidationError:
return Response({"errors": (vendor_serializer.errors,
vendor_contact_serializer.errors,
vendor_modules_serializer.errors
)},
status=status.HTTP_400_BAD_REQUEST)
else:
return Response(request.data, status=status.HTTP_200_OK)
There is no problem saving one Vendor model, but I can't imagine how to save cascading all related models in a single request.
save returns the newly saved object, which you can then pass into the subsequent save() methods:
vendor = vendor_serializer.save(user_id=request.user)
module = module_serializer.save()
vendor_module = vendor_modules_serializer.save(module=module, vendor=vendor)
vendor_contact = vendor_contact_serializer.save(vendor=vendor)
Models.py
from django.db import models
class BusinessType(models.Model):
method = models.CharField(max_length=25)
class Vendor(models.Model):
first_name = models.CharField(max_length=25)
middle_name = models.CharField(max_length=25)
last_name = models.CharField(max_length=25)
nick_name = models.CharField(max_length=10)
email = models.CharField(max_length=30)
company = models.CharField(max_length=25)
phone = models.CharField(max_length=15)
mobile = models.CharField(max_length=10)
fax = models.CharField(max_length=10)
billing_address_street = models.CharField(max_length=120)
billing_address_city = models.CharField(max_length=20)
billing_address_state = models.CharField(max_length=20)
billing_address_zip = models.CharField(max_length=6)
billing_address_country = models.CharField(max_length=20)
shipping_address_street = models.CharField(max_length=120)
shipping_address_city = models.CharField(max_length=20)
shipping_address_state = models.CharField(max_length=20)
shipping_address_zip = models.CharField(max_length=6)
shipping_address_country = models.CharField(max_length=20)
notes = models.CharField(max_length=120)
gstin = models.CharField(max_length=25, null=True)
tin = models.CharField(max_length=25, null=True)
business_type = models.ForeignKey(BusinessType, on_delete=models.CASCADE)
Serializers.py
from rest_framework import serializers
from .models import Vendor,BusinessType
class BusinessTypeSerializer(serializers.HyperlinkedModelSerializer):
[enter image description here][1]
class Meta:
model = BusinessType
fields = ('id','method')
class VendorSerializer(serializers.HyperlinkedModelSerializer):
business_type = serializers.CharField(source='business_type.method')
class Meta:
model = Vendor
fields = ('id','first_name','middle_name','last_name','nick_name','email','company','phone','mobile','fax','billing_address_street','billing_address_city','billing_address_state','billing_address_zip','billing_address_country','shipping_address_street','shipping_address_city','shipping_address_state','shipping_address_zip','shipping_address_country','notes','gstin','tin','business_type')
In Django restframework, foreign key value is not getting in HyperlinkedModelserializer in 'business_type' field. When I tried to post method after declaring foreign key field, it says:
"AssertionError: The .create() method does not support nested
writable fields by default. Write an explicit .create() method for
serializer UserSerializer, or set read_only=True"
Im new to django. I have this model, In tblperson, only the forgein keys of type and status are saved. How do I join all tables to display their value not their forgein key? For example.
TblPerson.objects.raw('SELECT * FROM "Tblperson" INNER JOIN "Tblstatus" ON ("TblPerson"."Status" = "Tblstatus"."ID")'):
Thanks.
class TblPerson(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'ID')
Type = models.IntegerField(null=True, db_column=u'Type', blank=True)
Status = models.IntegerField(null=True, db_column=u'Status', blank=True)
class Meta:
db_table = u'tblPerson'
class Tblstatus(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'statStatusID')
Status = models.CharField(max_length=25, db_column=u'statStatus', blank=True)
class Meta:
db_table = u'tblStatus'
class Tbltype(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'typTypeID')
Type = models.CharField(max_length=25, db_column=u'typType', blank=True)
class Meta:
db_table = u'tblType'
The power of Django is in the ORM, which means you should be writing very little SQL if at all.
class Person(models.Model):
#don't use this because id is generated automatically
#ID = models.AutoField(primary_key=True, db_column=u'ID')
type = models.ForeignKey(Type)
status = models.ForeignKey(Status)
#Type,Status analogous
#filter like this
selected = Person.objects.filter(type=SomeType)
for p in selected:
print p.id,p.type,p.status
I would suggest you to re-write your models. So, that your TblPerson has a many to one relationship with Tblstatus
class TblPerson(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'ID')
Type = models.IntegerField(null=True, db_column=u'Type', blank=True)
Status = models.ForeignKey(Tblstatus, null=True, db_column=u'Status', blank=True)
class Meta:
db_table = u'tblPerson'
class Tblstatus(models.Model):
ID = models.AutoField(primary_key=True, db_column=u'statStatusID')
Status = models.CharField(max_length=25, db_column=u'statStatus', blank=True)
class Meta:
db_table = u'tblStatus'
Using this you would be able to query for TblPerson objects for which Tblstatus exists like this
TblPerson.objects.filter(Status__isnull=False)
my verbose_name of a foreignkeyfield isn't printed in my forms. (I create the modelforms via modelformset_factory
model
class MOrders(models.Model):
amount = models.IntegerField('Bestellmenge', null=True, blank=True)
order_date = models.DateField('Bestelldatum')
id = models.AutoField(primary_key=True)
m_product_types = models.ForeignKey(MProductTypes)
class Meta:
db_table = u'm_orders'
verbose_name = 'Bestellung'
verbose_name_plural = 'Bestellungen'
unique_together = (('id','order_date','m_product_types'))
def __unicode__(self):
return "%s" % (self.order_date)
verbose_name of m_product_types is set. B
class MProductTypes(models.Model):
id = models.AutoField(primary_key=True)
stock = models.IntegerField('Bestand',null=True, blank=True)
m_products = models.ForeignKey(MProducts, verbose_name='Produkt')
m_sizes = models.ForeignKey(MSizes, verbose_name='Groesse')
m_colors = models.ForeignKey(MColors, verbose_name='Farbe')
class Meta:
verbose_name = u'Produktart'
verbose_name_plural = 'Produktarten'
db_table = u'm_product_types'
Am I doing something wrong? I'm using the latest Django version from trunk.
m_product_types = models.ForeignKey(MProductTypes,
verbose_name = u'Produktart',
)