How to use left join orm? - django

My model
class Ad_company(models.Model):
idx = models.AutoField(primary_key=True)
subject = models.CharField(max_length=255)
memo = models.CharField(max_length=255)
content = models.TextField()
is_display = models.CharField(max_length=1)
writer = models.CharField(max_length=255)
write_date = models.DateTimeField()
update_date = models.DateTimeField()
delete_date = models.DateTimeField()
deadline_date = models.DateTimeField()
reply = models.IntegerField(blank=True)
hits = models.IntegerField(blank=True)
ad_apply = models.IntegerField(blank=True)
ad_category1 = models.CharField(max_length=255)
ad_category2 = models.CharField(max_length=255)
ad_place = models.CharField(max_length=255)
ad_age = models.CharField(max_length=255)
ad_sex = models.CharField(max_length=255)
ad_budget = models.BigIntegerField()
ad_length = models.CharField(max_length=255)
is_done = models.CharField(max_length=1)
is_pay = models.CharField(max_length=1)
ad_service = models.CharField(max_length=255)
ad_object = models.CharField(max_length=255)
is_file = models.CharField(max_length=1)
ad_require = models.CharField(max_length=255)
class Meta:
managed = False
db_table = 'ad_write_company'
class Ad_company_apply(models.Model):
idx = models.AutoField(primary_key=True)
parent_idx = models.IntegerField()
username = models.CharField(max_length=255)
content = models.TextField()
date = models.DateTimeField(default=datetime.now, blank=True)
budget = models.BigIntegerField()
term = models.IntegerField()
is_done = models.CharField(max_length=1)
SELECT * FROM ad_write_company INNER JOIN ad_write_company_apply ON ad_write_company.idx = ad_write_company_apply.parent_idx where ad_write_company_apply.is_done = 1 and ad_write_company_apply.username = 'asdffdsa'
This is my query. but I can not make join query with orm.
Sorry for question is too short.
And Is my query right?
I not sure of that. Thanks for answer.
or do you guys have other good idea?

I would advise to work with a ForeignKey from Ad_company_apply to Ad_company. This makes it easier to generate queries in Django and will guarantee referential integrity.
It thus makes sense to rewrite the Ad_company_apply model to:
class Ad_company_apply(models.Model):
# …
parent_idx = models.ForeignKey(
Ad_company,
db_column='parent_idx',
on_delete=models.CASCADE
)
# …
In that case, you can .filter(…) [Django-doc] with:
Ad_Company.objects.filter(ad_company_appy__isdone=1, ad_company_appy__username='asdffdsa')
Note: Models in Django are written in PascalCase, not snake_case,
so you might want to rename the model from Ad_company to AdCompany.

Related

how can i use django filter with multiple value select

I want to filter my data based on city , how can i filter my data if the user choose more than one city using django filter
class games(generics.ListAPIView):
queryset = Game.objects.filter(start_date__gte=datetime.today())
serializer_class=GameSerializers
filter_backends = [DjangoFilterBackend,filters.OrderingFilter]
filterset_fields = ['id','city','level']
game model
class Game(models.Model):
city = models.CharField(max_length=255)
gender = models.ForeignKey(Gender,on_delete=models.CASCADE)
level = models.ForeignKey(Level,on_delete=models.CASCADE)
host = models.ForeignKey(Host,on_delete=models.CASCADE)
start_date = models.DateTimeField()
end_date = models.DateTimeField()
fees = models.IntegerField()
indoor = models.BooleanField()
capacity = models.IntegerField()
age_from = models.IntegerField()
age_to = models.IntegerField()
description = models.CharField(max_length=255)
earned_points = models.IntegerField()
created_at = models.DateTimeField(default=django.utils.timezone.now)
image = models.ImageField(upload_to="GameImage",null=True)
history = HistoricalRecords()
Game.objects.filter(city__in=['Paris', 'London'])
Something like that ?
I'm not sure if this gonna work but try this:
filterset_fields = ['id','city__in','level']

Multiple try except in a serializer Django

I have a Warehouse model like the following:
class ShelfBin(models.Model):
bin_id = models.IntegerField(default=0)
bin_name = models.CharField(max_length=50, default=0)
class UnitShelf(models.Model):
shelf_id = models.IntegerField(default=0)
shelf_name = models.CharField(max_length=50, default=0)
bin = models.ManyToManyField(ShelfBin, blank=True)
class AisleUnit(models.Model):
unit_id = models.IntegerField(default=0)
unit_name = models.CharField(max_length=50, default=0)
shelf = models.ManyToManyField(UnitShelf, blank=True)
class ZoneAisle(models.Model):
aisle_id = models.IntegerField(default=0)
aisle_name = models.CharField(max_length=50, default=0)
unit = models.ManyToManyField(AisleUnit, blank=True)
class WarehouseZone(models.Model):
zone_id = models.IntegerField(default=0)
zone_name = models.CharField(max_length=50, default=0)
aisle = models.ManyToManyField(ZoneAisle, blank=True)
class Warehouse(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=250, default=0)
address = models.CharField(max_length=500, default=0)
zones = models.ManyToManyField(WarehouseZone, blank=True)
for this I have created a serializer like the following:
class WarehouseSerializer(serializers.ModelSerializer):
zones = WarehouseZonesSerializer(many=True)
class Meta:
model = Warehouse
fields = "__all__"
def create(self, validated_data):
print("validated data warehouse", validated_data)
zone_objects = validated_data.pop('zones', None)
instance = Warehouse.objects.create(**validated_data)
for item in zone_objects:
aisle_objects = item.pop('aisle')
wz_obj = WarehouseZone.objects.create(**item)
for data in aisle_objects:
unit_objects = data.pop('unit')
za_obj = ZoneAisle.objects.create(**data)
for u_data in unit_objects:
shelf_objects = u_data.pop('shelf')
au_obj = AisleUnit.objects.create(**u_data)
for s_data in shelf_objects:
bin_objects = s_data.pop('bin')
us_obj = UnitShelf.objects.create(**s_data)
for b_data in bin_objects:
b_obj = ShelfBin.objects.create(**b_data)
us_obj.bin.add(b_obj)
au_obj.shelf.add(us_obj)
za_obj.unit.add(au_obj)
wz_obj.aisle.add(za_obj)
instance.zones.add(wz_obj)
return instance
Now the problem is that sometimes warehouse can have zone, aisle, units, etc(all 5 sub-levels) but sometimes it can only be 1,2 or 0 level deep
and in that cases it raises error like this :
aisle_objects = item.pop('aisle')
KeyError: 'aisle'
So do I have to use try and except at each level of the loop or is there a better way to handle these exceptions?

How to migrate existing models to Wagtail Page models

I have a existed model,which is EmsanWorks(models.Model).
I would like to have a same page model, so I copy a new model and named it EmsanWorksPage and changed models.Model to Page.
class EmsanWorksPage(Page):
id_works = models.AutoField(primary_key=True)
name_r = models.CharField(max_length=255)
name_o = models.CharField(max_length=255)
title_r = models.TextField()
title_o = models.TextField()
title_t = models.TextField()
birth_y = models.CharField(max_length=20)
birth_c = models.ForeignKey(EmsanPays, models.DO_NOTHING, db_column='birth_c',related_name='page_emsanpays_birth_c')
gender = models.CharField(max_length=6)
dest = models.CharField(max_length=255)
media_spec = models.CharField(max_length=255)
year = models.TextField() # This field type is a guess.
commission = models.CharField(max_length=255)
performer = models.CharField(max_length=255)
first_perf = models.CharField(max_length=255)
duration = models.CharField(max_length=255)
perf_c = models.ForeignKey(EmsanPays, models.DO_NOTHING, db_column='perf_c')
context = models.TextField()
instr = models.TextField()
cycle = models.CharField(max_length=255)
media_w = models.CharField(max_length=255)
setup = models.CharField(max_length=255)
prod_loc = models.TextField()
prod_per = models.TextField()
perf_tech = models.TextField()
perf_media = models.TextField()
publisher = models.CharField(max_length=255)
audio = models.CharField(max_length=255)
prog_notes = models.TextField()
reception = models.TextField()
editor = models.CharField(max_length=255)
phono = models.CharField(max_length=255)
comment = models.TextField()
timestamp = models.DateTimeField()
modif = models.TextField()
afficher = models.CharField(max_length=3)
restricted_editors = models.TextField()
class Meta:
managed = False
db_table = 'emsan_works'
However, after migrate I got this error
OperationalError at /admin/emsanapp/emsanworkspage/
(1054, "Unknown column 'emsan_works.page_ptr_id' in 'field list'")

How to aggregate on a foreign key and a specific field at the same time?

My table named Value has a one to many relationship with the table Country and the table Output_outcome_impact. I have a query that is working fine and gets what I want but then I need to do an average of the value field, but this average needs to be done for each unique id_output_outcome_impact and not the whole query.
class Country(models.Model):
country_name = models.CharField(max_length=255, primary_key=True)
CONTINENTCHOICE = (
('Africa', 'Africa'),
('America', 'America'),
('Asia', 'Asia'),
('Europe', 'Europe'),
('Oceania', 'Oceania')
)
region = models.CharField(max_length=255)
continent = models.CharField(max_length=255, choices=CONTINENTCHOICE)
GDP_per_capita = models.IntegerField(null=True)
unemployment_rate = models.FloatField(null=True)
female_unemployment_rate = models.FloatField(null=True)
litteracy_rate = models.FloatField(null=True)
def __str__(self):
return self.country_name
class OutputOutcomeImpact(models.Model):
output_outcome_impact_name = models.CharField(max_length=255, primary_key=True)
TYPECHOICE = (
('Output', 'Output'),
('Outcome', 'Outcome'),
('Impact', 'Impact'),
)
type = models.CharField(max_length=255, choices=TYPECHOICE)
description = models.TextField()
TARGETGROUP = (
('Standard', 'Standard'),
('Investors', 'Investors'),
('Local authorities and NGOs', 'Local authorities and NGOs'),
)
target_group = models.CharField(max_length=255,choices=TARGETGROUP)
question = models.TextField(null=True, blank=True)
parent_name = models.ForeignKey('self', on_delete=models.PROTECT, null=True, blank=True)
indicator = models.ForeignKey(Indicator, on_delete=models.PROTECT)
def __str__(self):
return self.output_outcome_impact_name
class Activity(models.Model):
activity_name = models.CharField(max_length=255, primary_key=True)
description = models.TextField()
product_service = models.TextField()
output_outcome = models.TextField()
outcome_impact = models.TextField()
output_outcome_impacts = models.ManyToManyField('OutputOutcomeImpact')
countries = models.ManyToManyField('Country')
sectors = models.ManyToManyField('Sector')
def __str__(self):
return self.activity_name
class Value(models.Model):
value_name = models.CharField(max_length=255, primary_key=True)
country = models.ForeignKey(Country, on_delete=models.PROTECT)
id_output_outcome_impact = models.ForeignKey(OutputOutcomeImpact, on_delete=models.PROTECT)
value_has_source = models.ManyToManyField('Source')
value = models.FloatField()
function_name = models.CharField(max_length=255, default = "multiply")
def __str__(self):
return self.value_name
region_values = Value.objects.filter(id_output_outcome_impact__output_outcome_impact_name__in = output_pks, country_id__region = region).exclude(country_id__country_name = country).values()
So the result of the query is available below, and what I would like to achieve is to set the value field to an average of every object that has the same id_output_outcome_impact_id, here Dioxins and furans emissions reduction appears twice so I would like to get the 2 values set as their average.
<QuerySet [{'value_name': 'Waste_to_dioxins', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Dioxins and furans emissions reduction', 'value': 0.0003, 'function_name': 'multiply'}, {'value_name': 'Waste_to_dioxins_south_africa', 'country_id': 'South Africa', 'id_output_outcome_impact_id': 'Dioxins and furans emissions reduction', 'value': 150.0, 'function_name': 'multiply'}, {'value_name': 'Households getting electricity per kWh', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Households that get electricity', 'value': 0.0012, 'function_name': 'multiply'}, {'value_name': 'Dioxin to disease', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Reduction of air pollution related diseases', 'value': 0.31, 'function_name': 'multiply'}]>
I am wondering if django models allow such modification (I went through the doc and saw the annotate function with the average but couldn't make it work for my specific case), that would be nice. Thanks.
region_values = Value.objects.filter(id_output_outcome_impact__output_outcome_impact_name__in = output_pks, country_id__region = region).exclude(country_id__country_name = country).values('id_output_outcome_impact__output_outcome_impact_name').annotate(Avg('value'))

Get Foreign Key Value

How can I get the foreign key values? I have a common vehicle model that links to the year, series, engine type, body style, transmission and drive train...all as foreign keys. I'd like to get the values of these fields for my app, but I'm stuck as to how I'd go about them. Any ideas will be highly appreciated.
class Model(models.Model):
model = models.CharField(max_length=15, blank=False)
manufacturer = models.ForeignKey(Manufacturer)
date_added = models.DateField()
def __unicode__(self):
name = ''+str(self.manufacturer)+" "+str(self.model)
return name
class Year(models.Model):
ALPHA_NUMERIC_CHOICES = (
('1', 'Numeric'),
('A', 'Alphabetic'),
)
year = models.PositiveSmallIntegerField()
position_7_char = models.CharField(max_length=1, choices=ALPHA_NUMERIC_CHOICES)
position_10 = models.CharField(max_length=1, blank=False)
def __unicode__(self):
return unicode(self.year)
class Series(models.Model):
series = models.CharField(max_length=20, blank=True)
model = models.ForeignKey(Model)
date_added = models.DateField()
def __unicode__(self):
name = str(self.model)+" "+str(self.series)
return name
class CommonVehicle(models.Model):
year = models.ForeignKey(Year)
series = models.ForeignKey(Series)
engine = models.ForeignKey(Engine)
body_style = models.ForeignKey(BodyStyle)
transmission = models.ForeignKey(Transmission)
drive_train = models.ForeignKey(DriveTrain)
def __unicode__(self):
name = ''+str(self.year)+" "+str(self.series)
return name
class Vehicle(models.Model):
stock_number = models.CharField(max_length=6, blank=False)
vin = models.CharField(max_length=17, blank=False)
common_vehicle = models.ForeignKey(CommonVehicle)
exterior_colour = models.ForeignKey(ExteriorColour)
interior_colour = models.ForeignKey(InteriorColour)
interior_type = models.ForeignKey(InteriorType)
odometer_unit = models.ForeignKey(OdometerUnit)
status = models.ForeignKey(Status)
odometer_reading = models.PositiveIntegerField()
selling_price = models.PositiveIntegerField()
purchase_date = models.DateField()
sales_description = models.CharField(max_length=60, blank=False)
def __unicode__(self):
return self.stock_numberodels.ForeignKey(CommonVehicle)
You need the actual IDs? Try something like my_vehicle_ref.series.id.
Also, I hope you know that the series attribute right there is really an instance of Series, so you could access any of it's properties, e.g., my_vehicle_ref.series.model.model.