How i can return all relationships on recursive table on django
Structure(model):
class Category(models.Model):
name = models.CharField(max_length=100)
details = models.CharField(max_length=100)
state = models.IntegerField(default=1,choices=estado_choices,)
parent = models.ForeignKey('self', blank=True, null=True, related_name='category', db_index=False)
I would like return like this on template:
_______________________________________________
# |Category |name |description|
________________________________________________
1 | Principal |Example |example 3 |
2 | Subprincipal |subprincipal |example 3 |
3 | Subprincipal 2 |subprincipal 2| example3
i dont know how return this relationship.. please someone idea..!!
Rather that implementing a hierarchical category model of your own. Build on what others have done! There is a library called django-mptt that works very well for this. The documentation will tell you all you need to know about getting a recursive results from your categories.
Related
I've two models 'Students' and 'Enrollments'.
The schema for these is as below:
class Students(models.Model):
id = models.AutoField(primary_key=True, unique=True)
name = models.CharField()
class Enrollments(models.Model):
enroll_id = models.AutoField(primary_key=True, unique=True)
student_id = models.ForeignKey(Students, on_delete=models.CASCADE)
subjects = models.charField()
I'm trying to achieve the result of following SQL query in Django Rest Framework, for getting number of subjects enrolled by students (individually).
select
s.id, s.name, count(e.subjects) as count
from Students as s
left outer join Enrollments as e
on e.student_id_id = s.id
group by s.id, s.name, e.subjects
order by count asc;
This query returns result like:
---------------------------
| id | name | count |
---------------------------
| 1 | a | 1 |
| 2 | b | 0 |
| 3 | c | 2 |
---------------------------
Can anyone please help me acheive this kind of result.
Note: I need 0 count students details also.
What you can do is when you are creating a serializer, you can add a serializer method field which will get the count for you.
Add this at the top of your serializer:
count = serializers.SerializerMethodField('get_count')
Then add a function inside your serializer like this:
def get_count(self, obj):
try:
return Enrollments.objects.filter(student_id=obj.id).count()
except:
return None
Finally, add 'count' to your field list. You can then add as many fields as you want. I hope this will get you your desired result. Also don't forget to use "select_related" in the ORM inside your view to reduce the amount of queries.
models.py:
class Address(models.Model):
text = models.TextField(max_length=2060, null=True, blank=True, default=None, unique=True)
class Tag(models.Model):
text = models.CharField(max_length=255, null=True, blank=True, default=None, unique=True)
class AddressTagJoin(models.Model):
address = models.ForeignKey(Address, on_delete=models.CASCADE, null=True, blank=True, related_name='address_tag_join')
tag = models.ForeignKey(Tag, on_delete=models.CASCADE, null=True, blank=True, related_name='address_tag_join')
In above, Address and Tag objects are only used as AddressTagJoin's foreignkey target.
What I want to do is two kind of queryset..
When I got address "https://www.google.com", I want to get Tag queryset ordered by most used for Address (text = "www.google.com")
Tag.objects.order_by(count_of_AddressTagJoin_and_It's_address_foreignkey_is_for_"www.google.com")
In reverse, I got tag "google", I want to get Address queryset ordered by most how many used for Tag (text="google")
Address.objects.order_by(count_of_AddressTagJoin_and_It's_tag_foreignkey_is_for_"google")
How can I do that?
from what I understood, you require:
"For the address "google.com" most used tags in order"
By taking an example I'll reach to the query.
There is this table AddressTagJoin:
address__text | tag__id
"google.com" | 1
"google.com" | 2
"google.com" | 1
"yahoo.com" | 2
"google.com" | 3
"google.com" | 3
"google.com" | 3
If we filter AddressTagJoin based on address "google.com" and then group this based on tag__id to get the tag counts(for the address most used tags), ordering it we get:
tag__id | tag_count
3 | 3
1 | 2
2 | 1
The desired result which you want is:
tags --> 3, 1, 2
Query for this will be:
from django.db.models import Count
tags_list = list(
AddressTagJoin.objects.filter(address__text__icontains="www.google.com")
.values('tag__id')
.annotate(tag_count=Count('tag__id'))
.order_by('-tag_count')
.values_list('tag__id', flag=True)
)
tags = Tag.objects.filter(id__in=tags_list)
Note
Please check the query there might be little adjustments required. This will give you an idea for the second query, both are almost same.
Also, If you want to optimize this query you can use select_related in the tag_list query. You can refer to the docs here
PS: I haven't implemented the models to check the query because of time constraints.
In a few weeks I want to start building a "datawarehouse" based on django. The database should be filled with data which can be connected to a location. For example population which is connected to country or city, or the anual rainfall or temperature. The parameters are not yet defined and will change over time but they will in general have a quantity, timeperiod (for example anual) and unit (so in the example: population of country X in year Y).
My idea was to have a selfreferencing table in the database named locations in which there would be continents, countries, regions and cities. An example:
ID | parent_id | name
1 | null | Europe
2 | 1 | France
3 | 2 | Paris
I would than have a table which would connect data to a location like such:
ID | location_id | parameter_id | from_date | to_date | quantity
1 | 3 | 1 | 01-01-2000 | 31-01-2001 | 3000000
parameters:
ID | name | unit
1 | population | people
Technically I also want to couple locations to coordinates or polygons such that I can show them on a map.
Is something like this possible in (Geo)Django? I feel that GeoDjango couples a model class to a specific subject such as in this case population. However, I do not know my subjects yet..
Or should I design the database structure different altogether?
Lastly: I want to use a pgSQL with postgis database for this because it is opensource and seems most appropriate. However if I program the website locally I have SQLite, is there a way I can run a pgSQL with Postgis locally on my windows computer (which is rather slow) for development? Can I then easily push it using for example GitLab to a production location (for example amazone AWS)?
Tips and help on this subject is very much appreciated.
For hierarchical data with Django, use Django MPTT:
class Region(MPTTModel):
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
name = models.CharField(max_length=50, unique=True)
geom = models.MultiPolygonField(null=True, blank=True)
class Parameter(models.Model):
name = models.CharField(max_length=50, unique=True)
class RegionParameter(models.Model):
region = TreeForeignKey(Region, null=True, blank=True, related_name='children', db_index=True...)
param = models.ForeignKey(Parameter...)
from_date = models.DateField()
to_date = models.DateField()
value = models.IntegerField()
You can add the geographic data only on the leafs or to all levels in the hierarchy.
I'm trying to order a query by a self-referencing OneToOne field. The model:
class Foo(models.Model):
prior_foo = models.OneToOneField('self', related_name='following_foo', null=True, blank=True)
There is no guarantee that the pk for the linked item is higher or lower, (or any other field is useful besides the OneToOne reference) e.g.:
Foo.pk | prior_foo.pk
3 | null
6 | 3
5 | 6
10 | 5
I'd love to have the query return:
[foo_3, foo_6, foo_5, foo_10]
I am attempting to build a very general model that needs the flexibility of nesting. Here is a simple example.
Work Symphony No.1
|_Work |_Movement 1
| |_Work | |_Allegro
| |_Work | |_Largo
| |
|_Work |_Movement 2
|_Work |_Poco Allegretto
What I wish I could do throws a syntax error, since Work obviously hasn't been defined it can't be a ForeignKey.
class Work(models.Model):
work_name = models.CharField('Work Name', max_length=100)
work_parent = models.ForeignKey(Work)
I was thinking about using a base class like this:
class BaseWork(models.Model):
pass
class Work(BaseWork):
name = models.CharField(max_length=100)
work_parent = models.ForeignKey(BaseWork)
I believe that by doing that, I could make Fry his own grandfather so to speak but is there a 'correct' way to do this?
Thanks #Seether.
class Work(BaseWork):
name = models.CharField(max_length=100)
work_parent = models.ForeignKey('self', null=True)
I am curious about whether and why this would be bad practice. Surely there must be a lot of models out there that need to be nested right? Do they hardcode the structure?