simple django join query without foreign key - mysql

** Below are two models teacher and loginstudent, A teacher can teach multiple sections and multiple students can be in same section.So section field cannot be a foreign key.If I want to find out all courses taken by a particular student,what should I do? Is there any simple django query just like sql did.How to do?
**
class Teacher(models.Model):
username=models.CharField(max_length=50)
password=models.CharField(max_length=89)
course=models.CharField(max_length=30)
section=models.CharField(max_length=30)
class LoginStudent(models.Model):
username=models.CharField(max_length=50)
password=models.CharField(max_length=89)
section=models.CharField(max_length=30)

OK, I would recommend to stick to the default user system from Django and build one-to-one profiles of the specific type where needed. Latter on you can differentiate between the users based on the value of the foreign key or you could implement permissions which are tied to the user type
from django.db.models.query_utils import Q
# for example, this could be a way to extend users to hold teachers and students
class TeacherProfile(models.Model):
user = models.OneToOneField(User, related_name='teacher_profile')
# other relevant teacher profile items
ONLY_TEACHERS_FILTER = Q(teacher_profile__isnull=False) & Q(student_profile__isnull=True)
class StudentProfile(models.Model):
user = models.OneToOneField(User, related_name='student_profile')
# other relevant student profile items
sections = models.ManyToManyField('Section', related_name='students') # mind the quotes to Section name
class Section(models.Model)
name = models.CharField(max_length=50)
# other section fields goes here...
class Course(models.Model):
name = models.CharField(max_length=50)
teacher = models.ForeingKey(User, related_name='courses', limit_choices_to=ONLY_TEACHERS_FILTER)
sections = models.ManyToManyField(Section, related_name='courses')
Now to answer to the question what are the courses to which a student attends to:
queryset = Course.objects.filter(section__students__in=[user])
Hope it helps!

Related

Using the same form multiple times over a single column in a template Django

I gotta a school management web app. In my app teachers can create exams and then add grades to that. I've created a separate model for grades. This is my models right now:
class Grade(models.Model):
student = models.ForeignKey(
Student,
on_delete=models.CASCADE,
related_name="grade_user",
)
subject = models.ForeignKey(
Subject,
on_delete=models.CASCADE,
related_name="grade_subject",
)
grade = models.DecimalField(max_digits=6, decimal_places=2)
class Exam(models.Model):
...
grades = models.ManyToManyField(
Grade,
related_name="exam_grades",
blank=True,
)
Now I've created a form like following:
Teachers fill the fields and then using a single button this should be submitted. But the problem is that I don't know how to implement such implementation. I read somethings about formsets but I want the fields to be in a single column.
Is there any way to get this done?

multiple foreign keys on a django model

I am seeking to create a relational database design in Django where one table has relationships with multiple models in the DB.
The sample models are excerpted below.
from __future__ import unicode_literals
from django.db import models
class State(models.Model):
state_name = models.CharField(max_length=100, unique=True)
class District(models.Model):
state_id = models.ForeignKey(State, on_delete=models.CASCADE)
district_name = models.CharField(max_length=100)
class County(models.Model):
county_id = models.ForeignKey(County, on_delete=models.CASCADE)
district_id = models.ForeignKey(District, on_delete=models.CASCADE)
county_name = models.CharField(max_length=100, unique=True)
class Kiosk(models.Model):
county_id = models.ForeignKey(County, on_delete=models.CASCADE)
kiosk_name = models.CharField(max_length=100)
kiosk_type = models.CharField(max_length=100)
kiosk_size = models.CharField(max_length=100)
class Operator(models.Model):
kiosk_id = models.ForeignKey(County, on_delete=models.CASCADE)
operator_name = models.CharField(max_length=100)
The overall goal is to register kiosks and their operators in the administrative territories. All relationships between the models are one-to-many. Administrative territories are hierarchical from the States-Counties-Townships which according to the schema design leads to one table having many foreign keys. For example Township(state_id, county_id) and Kiosk(state_id, county_id, township_id) and so forth.
If such a design is appropriate, then how would i model it in Django such that a single model like kiosk has 2 or 3 foreign keys relating to the other models?
If i attempt to add foreign keys as it appears in the County model i get the following error on applying migrations.
You are trying to add a non-nullable field 'region_id' to county without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
It is obviously not the way to do it and i am seeking guidance from anyone who might have a solution to this problem.
I am working in Django 1.10.
Thank you all.

Django GenereicForeignKey v/s custom manual fields performance/optimization

I'm trying to build a typical social networking site. there are two types of objects mainly.
photo
status
a user can like photo and status. (Note that these two are mutually exclusive)
means, We have two table (1) for Image only and other for status only.
now when a user likes an object(it could be a photo or status) how should I store that info.
I want to design a efficient SQL schema for this.
Currently I'm using Genericforeignkey(GFK)
class LikedObject(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
but yesterday I thought if I can do this without using GFK efficiently?
class LikedObject(models.Model):
OBJECT_TYPE = (
('status', 'Status'),
('image', 'Image/Photo'),
)
user = models.ForeignKey(User, related_name="liked_objects")
obj_id = models.PositiveIntegerField()
obj_type = models.CharField(max_length=63, choices=OBJECT_TYPE)
the only difference I can understand is that I have to make two queries if I want to get all liked_status of a particular user
status_ids = LikedObject.objects.filter(user=user_obj, obj_type='status').values_list('object_id', flat=True)
status_objs = Status.objects.filter(id__in=status_ids)
Am I correct? so What would be the best approach in terms of easy querying/inserting or performance, etc.
You are basically implementing your own Generic Object, only you limit your ContentType to your hard coded OBJECT_TYPE.
If you are only going to access the database as in your example (get all status objects liked by user x), or a couple specific queries, then your own implementation can be a little faster, of course. But obviously, if later you have to add more objects, or do other things, you may find yourself implementing your whole full generic solution. And like they say, why reinvent the wheel.
If you want better performance, and really only have those two Models to worry about, you may just want to have two different Like tables (StatusLike and ImageLike) and use inheritance to share functionality.
class LikedObject(models.Model):
common_field = ...
class Meta:
abstract = True
def some_share_function():
...
class StatusLikeObject(LikedObject):
user = models.ForeignKey(User, related_name="status_liked_objects")
status = models.ForeignKey(Status, related_name="liked_objects")
class ImageLikeObject(LikedObject):
user = models.ForeignKey(User, related_name="image_liked_objects")
image = models.ForeignKey(Image, related_name="liked_objects")
Basically, either you have a lot of Models to worry about, and then you probably want to use the more Django generic object implementation, or you only have two models, and why even bother with a half generic solution. Just use two tables.
In this case, I would check if your data objects Status and Photo may have many common data fields, e.g. Status.user and Photo.user, Status.title and Photo.title, Status.pub_date and Photo.pub_date, Status.text and Photo.caption, etc.
Could you combine them into an Item object maybe? That Item would have a Item.type field, either "photo" or "status"? Then you would only have a single table and a single object type a user can "like". Much simpler at basically no cost.
Edit:
from django.db import models
from django.utils.timezone import now
class Item(models.Model):
data_type = models.SmallIntegerField(
choices=((1, 'Status'), (2, 'Photo')), default=1)
user = models.ForeignKey(User)
title = models.CharField(max_length=100)
pub_date = models.DateTimeField(default=now)
...etc...
class Like(models.Model):
user = models.ForeignKey(User, related_name="liked_objects")
item = models.ForeignKey(Item)

sqlalchemy relations and query on relations

Suppose I have 3 tables in sqlalchemy. Users, Roles and UserRoles defined in declarative way. How would one suggest on doing something like this:
user = Users.query.get(1) # get user with id = 1
user_roles = user.roles.query.limit(10).all()
Currently, if I want to get the user roles I have to query any of the 3 tables and perform the joins in order to get the expected results. Calling directly user.roles brings a list of items that I cannot filter or limit so it's not very helpful. Joining things is not very helpful either since I'm trying to make a rest interface with requests such as:
localhost/users/1/roles so just by that query I need to be able to do Users.query.get(1).roles.limit(10) etc etc which really should 'smart up' my rest interface without too much bloated code and if conditionals and without having to know which table to join on what. Users model already has the roles as a relationship property so why can't I simply query on a relationship property like I do with normal models?
Simply use Dynamic Relationship Loaders. Code below verbatim from the documentation linked to above:
class User(Base):
__tablename__ = 'user'
posts = relationship(Post, lazy="dynamic")
jack = session.query(User).get(id)
# filter Jack's blog posts
posts = jack.posts.filter(Post.headline=='this is a post')
# apply array slices
posts = jack.posts[5:20]

M2M between two different apps

I have two models in separate apps:
# Groups app
class Group(models.Model):
name = models.CharField(max_length=256)
abbreviation = models.CharField(max_length=32)
admin = models.ManyToManyField('UserProfile')
# UserProfile app
class UserProfile(models.Model):
user = models.OneToOneField(User)
groups = models.ManyToManyField(Group)
In other words, a user may belong to several groups (User M2M to Groups), and also a group may have one or more administratrators (Group M2M to Users). I am having trouble with doing a syncdb here because of this. What would be the best way to proceed here? Should I 1) combine Groups into the UserProfile app? or 2) user ALTER TABLE statements after the fact to make one of the M2M links? or 3) Something else?
https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey
class Group(models.Model):
name = models.CharField(max_length=256)
abbreviation = models.CharField(max_length=32)
admin = models.ManyToManyField('userprofile.UserProfile')