I'm trying to join tables by using Django queryset, but for some reason it keeps throwing an error.
Tables are structured as below.
class Platform(models.Model):
P_key = models.AutoField(primary_key=True)
P_url = models.CharField(max_length=100)
P_userkey = models.IntegerField(default=0)
P_name = models.CharField(max_length=10)
objects = models.Manager()
class User_info(models.Model):
U_key = models.AutoField(primary_key=True)
U_name = models.CharField(max_length=20)
U_img = models.CharField(max_length=100)
U_info = models.CharField(max_length=100)
U_sudate = models.CharField(max_length=20)
P_key = models.ForeignKey(Platform, on_delete=models.CASCADE)
objects = models.Manager()
This is the code written to join two tables together.
queryset = User_info.objects.all().prefetch_related("Platform")
queryset = User_info.objects.all().select_related("Platform")
queryset = Platform.objects.all().select_related("User_info")
And the following is the error:
django.core.exceptions.FieldError: Invalid field name(s) given in
select_related: 'Platform'. Choices are: P_key.
I've tried a number of query sets but I wasn't able to get far.
you have to use field names
queryset = User_info.objects.all().prefetch_related("P_key")
queryset = User_info.objects.all().select_related("P_key")
Related
Hi i have 3 models in my django projects, when user send request i have his dealer_id i need return query set with info about material from Material table and for each row add discount_percent from last model where dealer_id = current dealer_id and row id. Please help me if you have answer.
models
class Material(models.Model):
id = models.AutoField(primary_key=True)
color = models.IntegerField()
name = models.CharField(max_length=100)
material_width = models.IntegerField()
price = models.BigIntegerField(default=0)
class Dealer(models.Model):
id = models.AutoField(primary_key=True)
dealer_name = models.CharField(max_length=100)
dealer_phone = models.CharField(max_length=13, unique=True)
dealer_email = models.CharField(max_length=150, null=False, unique=True)
dealer_firm_name = models.CharField(max_length=100, null=True)
dealer_address = models.CharField(max_length=100, null=True)
dealer_unp = models.CharField(max_length=9, null=True)
dealer_amount = models.FloatField(default=0.0)
user_id = models.BigIntegerField(unique=True)
class MaterialDealerPrice(models.Model):
id = models.AutoField(primary_key=True)
dealer_id = models.BigIntegerField(null=False)
material_id = models.BigIntegerField(null=False)
discount = models.FloatField(null=True, default=0.0)
This looks like a set of models that were automatically created by running inspectdb. You should always treat that output as a first draft; there is a lot that needs to be done manually to tidy it up.
Firstly, your MaterialDealerPrice model needs to have foreign keys to Dealer and Material:
class MaterialDealerPrice(models.Model):
dealer = models.ForeignKey('Dealer', null=False)
material = models.ForeignKey('Material', null=False)
discount = models.FloatField(null=True, default=0.0)
Secondly, you should recognise that this model is in fact the through table of a many-to-many relationship.
class Material(models.Model):
...
dealers = models.ManyToManyField('Dealer', through='MaterialDealerPrice')
Now, you should be able to follow these relationships in your query. Unfortunately your question is not clear enough to know what you actually want to do; you should give an example of the desired output.
Annotate can be used for this purpose. https://docs.djangoproject.com/en/1.11/topics/db/aggregation/
I am using DRF to serialize and have the api endpoints to display json data.
I have 2 models -
class FooOne(models.Model):
field_a = models.CharField(max_length=255, null=False)
field_b = models.CharField(max_length=255, null=False)
field_c = models.CharField(max_length=255, null=False)
class FooTwo(models.Model):
field_fk = models.ForeignKey(FooOne)
field_d = models.CharField(max_length=255, null=False)
field_e = models.CharField(max_length=255, null=False)
these are my serializer classes -
class FooOneSerializer(serializers.ModelSerializer):
class Meta:
model = FooOne
fields = (field_a, field_b, field_c)
class FooTwoSerializer(serializers.ModelSerializer):
field_fk = FooOneSerializer()
class Meta:
model = FooTwo
fields = (field_fk, field_d, field_e)
FooTwoSerializer will return data with field_fk as a nested dictionary. What i want to is to return other fields of FooOneSerialzer that arent foreign key to FooTwo and append it the final rendered result of FooTwoSerializer.
How do i go about this?
If I understand well, you want concatenate the results of FooOneSerailizer and all fields of FooTwoSerializer. You can do so by overriding to_represetation() method.
class FooTwoSerializer(serializers.ModelSerializer):
class Meta:
model = FooTwo
fields = (field_d, field_e)
def to_representation(self, instance):
# get OrderedDict with original fields
response = super(FooTwoSerializer, self).to_representation(instance)
# get OrderedDict with foreign foo_one data
foo_one = FooOneSerializer(instance.field_fk).data
# set this fields to original data
for key in foo_one:
response[key] = foo_one[key]
return response
Try to serialize this Models
Model:
class Order (models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
summ =models.CharField(max_length=15,default='0')
delivery = models.ForeignKey('Delivery')
success = models.BooleanField(default=False)
paymentMethod = models.ForeignKey('Payments')
def __unicode__(self):
return unicode(self.id)
class OrderProduct(models.Model):
order=models.ForeignKey('Order')
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
price = models.IntegerField()
product = models.ForeignKey('product.Product')
additionals = models.IntegerField(null=True,default=0)
count = models.IntegerField()
def __unicode__(self):
return self.id
class Delivery(models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
delivery_time = models.DateTimeField()
delivery_adress = models.TextField()
phone = models.TextField()
def __unicode__(self):
return self.phone
class Payments(models.Model):
id = models.AutoField(primary_key=True)
date_create = models.DateField(auto_now_add=True)
date_change = models.DateField(auto_now=True)
title = models.TextField();
def __unicode__(self):
return self.title
Serializers:
class DeliverySerializer(serializers.ModelSerializer):
class Meta:
model = Delivery
fields = ('id', 'delivery_time','delivery_adress','phone')
def create(self, validated_data):
return Delivery.objects.create(**validated_data)
class PaymentsSerializer(serializers.ModelSerializer):
class Meta:
model = Payments
fields = ('id', 'title')
def create(self, validated_data):
return Payments.objects.create(**validated_data)
class OrderSerializer(serializers.ModelSerializer):
delivery = DeliverySerializer(read_only=True)
paymentMethod = PaymentsSerializer(read_only=True)
class Meta:
model = Order
fields = ('id', 'delivery', 'paymentMethod','summ','success')
def create(self, validated_data):
deliverys_data = validated_data.pop('delivery')
paymentsMethod_data = validated_data.pop('paymentMethod')
order = Order.objects.create(**validated_data)
for delivery_data in deliverys_data:
Delivery.objects.create(order=order, **delivery_data)
for paymentMethod_data in paymentsMethod_data:
Payments.objects.create(order=order, **paymentMethod_data)
return order
View:
#api_view(['POST'])
def order_post(request, format=None):
#List all snippets, or create a new snippet.
if request.method == 'POST':
serializer = OrderSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
I need to get data by 1 packet, and then write data in DB
EveryTime I get a error:
deliverys_data = validated_data.pop('delivery')
KeyError: 'delivery'
Example of JSON packet
[{"delivery":{"delivery_time":"2016-05-31T12:18:47Z","delivery_adress":"123","phone":"123"},"paymentMethod":{"id":1,"title":"123124123"},"summ":"23","success":false}]
You are getting KeyError: 'delivery' because you have set delivery field as read_only. If DRF finds this field in the input, it will ignore that field.
From docs on read_only argument:
Read-only fields are included in the API output, but should not be
included in the input during create or update operations. Any
'read_only' fields that are incorrectly included in the serializer
input will be ignored.
Also, since you are using paymentMethod field in the create() method, you need to tell DRF to consider that field also in the input.
So, you need to remove the read_only argument from your serializer for both delivery and paymentMethod fields so that these fields are considered when deserializing.
class OrderSerializer(serializers.ModelSerializer):
delivery = DeliverySerializer() # remove read_only argument
paymentMethod = PaymentsSerializer() # remove read_only argument
Secondly, you are sending the data incorrectly. You need to send a single order input instead of list of orders you are sending.
# send without the list
{"delivery":{"delivery_time":"2016-05-31T12:18:47Z","delivery_adress":"123","phone":"123"},"paymentMethod":{"id":1,"title":"123124123"},"summ":"23","success":false}
EveryTime I get a error: deliverys_data = validated_data.pop('delivery') KeyError: 'delivery'
This is to be expected since the OrderSerialzier has DeliverySerializer flagged as read_only.
If you want to get the data writable, you'll need to remove that flag first.
I am trying to return JSON or even a complete string of a returned one to many sqlalchemy query. I am using Marshmallow at this point to try do it but it keeps returning incomplete data
I have two models defined as :
class UserModel(db.Model):
__tablename__ = 'usermodel'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
password = db.Column(db.String(120))
weekday = db.relationship('weekDay', cascade='all,delete-orphan', single_parent=True, backref=db.backref('usermodel', lazy='joined'))
class weekDay(db.Model):
__tablename__ = 'weekday'
id = db.Column(db.Integer, primary_key=True)
#Defining the Foreign Key on the Child Table
dayname = db.Column(db.String(15))
usermodel_id = db.Column(db.Integer, db.ForeignKey('usermodel.id'))
I have defined two schemas
class WeekdaySchema(Schema):
id = fields.Int(dump_only=True)
dayname = fields.Str()
class UserSchema(Schema):
id = fields.Int(dump_only=True)
username = fields.Str()
password = fields.Str()
weekday = fields.Nested(WeekdaySchema)
and finally I run the command (I pass the name in userName variable)
userlist = UserModel.query.filter_by(parentuser=userName).all()
full_schema = UserSchema(many=True)
result, errors = full_schema.dump(userlist)
print (result)
I print the result to see before I attempt to Jsonify it:
My weekday object is completely empty
'weekday': {}
Doesn anyone know how I can do this correctly
It's a one-to-many relationship and you must indicate it on UserSchema, like that
class UserSchema(Schema):
id = fields.Int(dump_only=True)
username = fields.Str()
password = fields.Str()
weekday = fields.Nested(WeekdaySchema, many=True)
read more on documentation
Hi I have a project in PHP and I want develop the same with Django, for many reasons I decided to create a new database, so now I have to export all the data from the old one to the new one,for doing that I use the models I developed for Django, it worked until I stuck with this error:
_mysql_exceptions.Warning: Data truncated for column 'bloomberg' at row 1
this is the model of the table where I am experimenting this issue:
class Contact(models.Model):
company_id = models.ForeignKey(Company)
address = models.CharField(max_length=150)
first_name= models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
role = models.CharField(max_length=20)
sector = models.CharField(max_length=45)
work_phone = models.CharField(max_length=30)
contact_source = models.CharField(max_length=30)
alt_work_phone = models.CharField(max_length=30)
mobile_phone = models.CharField(max_length=30)
work_fax = models.CharField(max_length=30)
bloomberg = models.CharField(max_length=60)
work_email = models.CharField(max_length=60)
research_email = models.CharField(max_length=60)
product_focus = models.CharField(max_length=2)
preferred_email = models.CharField(max_length=60)
job_title = models.CharField(max_length=80)
created_by = models.CharField(max_length=25)
legal_entity_name = models.CharField(max_length=100)
status= models.ForeignKey(Status)
title = models.CharField(max_length=5)
zipcode = models.CharField(max_length=10)
country = models.CharField(max_length=15)
city= models.CharField(max_length=20)
created_date=models.DateTimeField('creation date ')
updated_date=models.DateTimeField('update date ')
updated_by = models.CharField(max_length=20)
parent = models.CharField(max_length=45)
address_line_2 = models.CharField(max_length=100)
new = models.BooleanField()
hided = models.BooleanField()
employee = models.BooleanField()
def __unicode__(self):
s = u" Contact "
return s + self.first_name + " " + self.last_name
the fields in both databases have the same length,so I do not understand the error, after googling I noticed that usually this problem is solved fixing the dimensions of the column, but this is not my case. can somebody tell me how to fix it?
it looks like 60 Chars are not enough for your "bloombergs". Try to set this higher like:
bloomberg = models.CharField(max_length=255)
Notice, that you will also have to do this on database level if you already synced your models. Hope this helps.