How to annotate field by filer from manytomanyfield - python

my models
class Project(models.Model):
name = models.CharField(max_length=255, unique=True)
info = models.CharField(max_length=255, unique=True)
m2mStatus = models.ManyToManyField("ProjectStatus")
class ProjectStatus(models.Model):
status = models.BooleanField(default=False)
startTime = models.DateTimeField(auto_now=True)
description = models.CharField(max_length=255)
I want to annotate like this:
pj = Project.objects.filter(name="abc")
ps = pj.m2mStatus.last()
Project.objects.filter(name="abc").annotate(status=ps.status)
any help ?

Related

"Got KeyError when attempting to get a value for field devUserId on serializer AssetSerializer. Original exception text was: 'devUserId'

models.py
class User(models.Model):
googleId = models.CharField(max_length=512, primary_key=True, default='')
imageURL = models.CharField(max_length=512, null=True)
userName = models.CharField(max_length=512, null=True)
firstName = models.CharField(max_length=512, null=True)
lastName = models.CharField(max_length=512, null=True)
#phoneNumberRegex = RegexValidator(regex=r"^+?1?\d{8,15}$")
phoneNumber = models.CharField(max_length=512, null=True)
email1 = models.CharField(max_length=512, blank=False)
email2 = models.CharField(max_length=512, blank=True)
bio = models.TextField(blank=True)
planId = models.ForeignKey('primal_user.Plans',
on_delete=models.CASCADE,
default="Free")
password = models.CharField(max_length=512, null=True)
accountCreationDate = models.DateTimeField(auto_now_add=True)
coins = models.IntegerField(default=2)
assetsDownloaded = models.IntegerField(default=0)
assetsPurchased = models.IntegerField(default=0)
class Asset(models.Model):
assetId = models.CharField(max_length=20, primary_key=True)
devUserId = models.ForeignKey(User, on_delete=models.CASCADE)
keywordId = models.ForeignKey(Tags, on_delete=models.CASCADE)
assetName = models.CharField(max_length=50, null=False)
description = models.TextField(blank=True)
features = models.TextField(blank=True)
uploadedDate = models.DateField(auto_now_add=True)
typeId = models.BooleanField(default=True)
paidStatus = models.BooleanField(default=False)
price = models.IntegerField(null=True)
size = models.FloatField(null=False)
downloadCount = models.BigIntegerField(null=True)
version = models.CharField(max_length=10)
serializer.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
class AssetSerializer(serializers.ModelSerializer):
class Meta:
model = Asset
fields = '__all__'
views.py
class UserAsset(APIView):
def get(self,request,devUserId):
try:
user = Asset.objects.filter(devUserId=devUserId).values()
serializer = AssetSerializer(user, many= True)
return Response(serializer.data)
except Asset.DoesNotExist:
raise Http404
KeyError
I am a beginner in Django, so am unable to figure out what the issue is. I tried looking for solutions to similar questions but could not resolve the issue. I was getting attribute error, then it was resolved after I entered many=True in AssetSerializer but now I am stuck with this KeyError. A while trying to figure out the error, I noticed that this error is thrown while executing serializer.data. Thank You for any help possible.
In your code, just a small change is needed in syntax.
Instead of:
user = Asset.objects.filter(devUserId=devUserId).values()
Write:
user = Asset.objects.filter(devUserId=devUserId)
And that should solve the issue!
try with user = Asset.objects.values('fieldnamehere').filter(devUserId=devUserId)

Access child model attributes in django templates

I have created model inheritance in django models like:
models.py
class Instance(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, related_name='instances')
name = models.CharField(max_length=255, name='name')
slug = AutoSlugField(populate_from='name', unique=True)
created_at = models.DateTimeField(default=timezone.now, editable=False)
type = models.CharField(max_length=255, name='type', default='')
class Meta:
ordering = ['-created_at']
class CustomInstance(Instance):
serverCode = models.TextField(default='', blank=False)
jsonPackageCode = models.TextField(default='', blank=False)
type = models.CharField(max_length=255, name='type', default='custom')
class AwdInstance(Instance):
archive = models.FileField(upload_to='archives', name='archive')
type = models.CharField(max_length=255, name='type', default='awd')
class AwodInstance(Instance):
archive = models.FileField(upload_to='archives', name='archive')
type = models.CharField(max_length=255, name='type', default='awod')
class GithubInstance(Instance):
archive = models.CharField(max_length=255)
type = models.CharField(max_length=255, name='type', default='github')
How can I get child model fields in django templates like user.instances.serverCode?
Help me, please!
Thanks in advance!

Query using Joins in Django

class Students(models.Model):
id = models.BigAutoField(primary_key=True)
admission_no = models.CharField(max_length=255)
roll_no = models.CharField(unique=True, max_length=50, blank=True, null=True)
academic_id = models.BigIntegerField()
course_parent_id = models.BigIntegerField()
course_id = models.BigIntegerField()
first_name = models.CharField(max_length=20)
middle_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
user_id = models.BigIntegerField()
date_of_birth = models.DateField(blank=True, null=True)
date_of_join = models.DateField(blank=True, null=True)
class Courses(models.Model):
id = models.BigAutoField(primary_key=True)
parent_id = models.IntegerField()
course_title = models.CharField(max_length=50)
slug = models.CharField(unique=True, max_length=50)
tenant_user = models.ForeignKey('Users', models.DO_NOTHING, default='')
course_code = models.CharField(max_length=20)
course_dueration = models.IntegerField()
grade_system = models.CharField(max_length=10)
is_having_semister = models.IntegerField()
is_having_elective_subjects = models.IntegerField()
description = models.TextField()
status = models.CharField(max_length=8)
created_at = models.DateTimeField(blank=True, null=True)
updated_at = models.DateTimeField(blank=True, null=True)
class Meta:
managed = True
db_table = 'courses'
def __unicode__(self):
return self.course_title
class StudentProfileSerializer(ModelSerializer):
class Meta:
model = Students
depth = 0
fields = '__all__'
The first two tables/class contains the course and student table and the third contains the serializer. Can anyone please help how to query using the joins in django. I need to fetch the course_title from Courses table and first_name from Students table.
IMHO, you should review your models; course_id in Students should be a course=models.ForeignKey('Courses', ...); this way you can refer to the course title using dot notation;
student=Student.objects.filter(pk=...)
to refer to your required fields:
student.last_name, student.course.course_title
Besides, if I understood your models, you could get some incongruence... what if the value stored in course_parent_id in Students model is different from the value stored in parent_id in Courses model? maybe the first one is redundant.
To query a field from a related object use a double underscore. So you could do
Student.objects.filter(**kwargs).values('first_name', 'last_name', 'course__course_name')

DRF - filter across 2 models

I'm working with a legacy database where I have a serializer setup on Table A like so -
class TblapplicationsSerializer(serializers.ModelSerializer):
class Meta:
model = Tblapplications
fields = ('applicationid', 'applicationname', 'description', 'drtierid', 'saglink', 'supportinstructions',
'defaultincidentpriorityid', 'applicationorigintypeid', 'installationtypeid', 'comments',
'lastmodifieddate', 'lastmodifiedby', 'assetstatusid', 'recordownerid', 'adl_app')
depth = 2
I'm using a standard filter -
class TblapplicationsFilter(django_filters.FilterSet):
name = django_filters.CharFilter(name="applicationname", lookup_type="exact")
env = django_filters.CharFilter(name="adl_app__environmentid__domain")
class Meta:
model = Tblapplications
fields = ['applicationname', 'name', 'env']
Here's where it goes sideways. What I want to be able to do is filter on my URL like /api/applications/?name=xxx&env=DEV. It would then return the application and any databases that are linked with the environment of DEV. The name was understandably easy, but the only was I figured out the environment was to make the api point for applications touch the middle table that links the two but it returns multiple values because it's grabbing each time application is referenced with a separate database.
I've updated the Serializer and Filter based on comments given and the serializer, without the &env=DEV returns all the appropriate data (domain is nested in a reverse relationship). I then want my filter to filter the results based on that. Which means that it needs to somehow know to limit the results on the reverse relationship to only what's provided from the nested value.
If you see my models -
class Tblapplicationdatabaselinks(models.Model):
id = models.AutoField(db_column='ID', primary_key=True)
applicationid = models.ForeignKey('Tblapplications', db_column='applicationId', to_field='applicationid',
related_name='adl_app')
dbid = models.ForeignKey('Tbldatabases', db_column='dbId', to_field='id', related_name='adl_db')
environmentid = models.ForeignKey('Tbldomaincodes', db_column='environmentId', to_field='id',
related_name='adl_envlink')
comments = models.TextField(blank=True)
lastmodifieddate = models.DateTimeField(db_column='lastModifiedDate', blank=True, null=True)
lastmodifiedby = models.CharField(db_column='lastModifiedBy', max_length=255, blank=True)
# upsize_ts = models.TextField(blank=True) # This field type is a guess.
class Meta:
managed = False
db_table = 'tblApplicationDatabaseLinks'
class Tblapplications(models.Model):
applicationid = models.AutoField(db_column='applicationId', primary_key=True)
applicationname = models.CharField(db_column='applicationName', max_length=255)
description = models.TextField(blank=True)
drtierid = models.ForeignKey(Tbldomaincodes, db_column='drTierID', blank=True, null=True, to_field='id',
related_name='app_drtier')
saglink = models.TextField(db_column='sagLink', blank=True)
supportinstructions = models.TextField(db_column='supportInstructions', blank=True)
defaultincidentpriorityid = models.IntegerField(db_column='defaultIncidentPriorityId', blank=True, null=True)
applicationorigintypeid = models.IntegerField(db_column='applicationOriginTypeId')
installationtypeid = models.ForeignKey(Tbldomaincodes, db_column='installationTypeId', to_field='id',
related_name='app_insttype')
comments = models.TextField(blank=True)
assetstatusid = models.ForeignKey(Tbldomaincodes, db_column='assetStatusId', to_field='id',
related_name='app_status')
recordownerid = models.ForeignKey(Tblusergroups, db_column='recordOwnerId', blank=True, null=True,
to_field='groupid', related_name='app_owner')
lastmodifieddate = models.DateTimeField(db_column='lastModifiedDate', blank=True, null=True)
lastmodifiedby = models.CharField(db_column='lastModifiedBy', max_length=255, blank=True)
# upsize_ts = models.TextField(blank=True) # This field type is a guess.
class Meta:
managed = False
db_table = 'tblApplications'
class Tbldatabases(models.Model):
dbid = models.AutoField(db_column='dbId', primary_key=True)
dbname = models.CharField(db_column='dbName', max_length=255)
serverid = models.ForeignKey('Tblservers', db_column='serverId', to_field='serverid', related_name='db_serv')
servicename = models.CharField(db_column='serviceName', max_length=255, blank=True)
dbtypeid = models.IntegerField(db_column='dbTypeId', blank=True, null=True)
inceptiondate = models.DateTimeField(db_column='inceptionDate', blank=True, null=True)
comments = models.TextField(blank=True)
assetstatusid = models.IntegerField(db_column='assetStatusId')
recordownerid = models.IntegerField(db_column='recordOwnerId', blank=True, null=True)
lastmodifieddate = models.DateTimeField(db_column='lastModifiedDate', blank=True, null=True)
lastmodifiedby = models.CharField(db_column='lastModifiedBy', max_length=255, blank=True)
# upsize_ts = models.TextField(blank=True) # This field type is a guess.
class Meta:
managed = False
db_table = 'tblDatabases'
class Tbldomaincodes(models.Model):
id = models.IntegerField(db_column='ID', primary_key=True)
domain = models.CharField(primary_key=True, max_length=255)
displayname = models.CharField(db_column='displayName', primary_key=True, max_length=255)
displayorder = models.IntegerField(db_column='displayOrder', blank=True, null=True)
comments = models.TextField(blank=True)
lastmodifieddate = models.DateTimeField(db_column='lastModifiedDate', blank=True, null=True)
lastmodifiedby = models.CharField(db_column='lastModifiedBy', max_length=255, blank=True)
# upsize_ts = models.TextField(blank=True) # This field type is a guess.
class Meta:
managed = False
db_table = 'tblDomainCodes'
Extend your filter set and reference the field in the other model:
class TblapplicationsFilter(django_filters.FilterSet):
name = django_filters.CharFilter(name="applicationname", lookup_type="exact")
env = django_filters.CharFilter(name="environmentid__name")
# ^^^^^^^^^^^^^^^^^^^
class Meta:
model = Tblapplications
fields = ['applicationname', 'name', 'env']
Also, you may wish to name your ForeignKey fields without the id suffix, which is the Django convention. In Django, when you access Tblapplications.environmentid, it is normally a model instance, not the actual id integer itself.

Filtering two models

I have a problem with following thing: using models described below, I need to search for a car, that has more than x km of mileage and latest visit has date of more than year ago. Of course one car can have more than one visit.
class Car(models.Model):
...
id = models.CharField(max_length=10, primary_key=True, db_index=True)
mileage = models.PositiveIntegerField(db_index=True)
class Visit(models.Model):
...
id = models.ForeignKey(Car, db_column='id', db_index=False)
date = models.DateField(db_index=True)
In views.py I have code like this
def search_car(request):
time_threshold = datetime.now() - timedelta(days=365)
cars = Car.objects.filter(mileage__gte=500000,
id=Visit.objects.filter(data__lt=time_threshold.date()))
return render(request, 'myapp/search_car.html', {'cars': cars})
Unfortunately, it doesn't work. Any ideas?
EDIT Exact code:
models.py
class Samochod(models.Model):
marka = models.CharField(max_length=30)
model = models.CharField(max_length=30)
nr_rejestracyjny = models.CharField(max_length=10, primary_key=True, db_index=True)
nr_VIN = models.CharField(max_length=17, unique=True, validators=[validators.MinLengthValidator(17)])
przebieg = models.PositiveIntegerField(db_index=True)
id_uzytkownika = models.ForeignKey(User, db_column='id_uzytkownika', db_index=True)
class Wizyta(models.Model):
id_wizyty = models.IntegerField(primary_key=True, db_index=True)
data = models.DateField(db_index=True)
status = models.CharField(max_length=6, choices=STAN_CHOICE, db_index=True)
id_uzytkownika = models.ForeignKey(User, db_column='id_uzytkownika', db_index=True)
nr_rejestracyjny = models.ForeignKey(Samochod, db_column='nr_rejestracyjny', db_index=False)
przebieg_w_momencie_wizyty = models.PositiveIntegerField()
opis = models.CharField(max_length=200)
id_czesci = models.ForeignKey(Czesci, db_column='id_czesci')
cena = models.PositiveIntegerField()
czas_pracownikow = models.PositiveIntegerField(validators=[validators.MaxValueValidator(1000)])
id_sprzetu = models.ForeignKey(Sprzet, db_column='id_sprzetu', db_index=True)
views.py
def search_car(request):
time_threshold = datetime.now() - timedelta(days=365)
samochody = Samochod.objects.distinct().filter(przebieg__gte=500000).exclude(wizyta__date__gte=time_threshold)
return render(request, 'warsztat_app/search_car.html', {'samochody': samochody})
cars = Car.objects.distinct().filter(mileage__gte=500000) \
.exclude(visit__date__gte=time_threshold)
For your real models code should look like this:
samochody = Samochod.objects.distinct().filter(przebieg__gte=500000) \
.exclude(wizyta__data__gte=time_threshold)

Categories