How can make my model so that its ManyToMany Refer to User
class User(AbstractUser):
teacher_or_student = models.CharField(max_length=100)
mobile_number = models.CharField(max_length=100)
grade = models.CharField(max_length=100)
laptop_yes_or = models.CharField(max_length=100)
students = models.ManyToManyField(User)
You can pass the 'self' string for this. By default a ManyToManyField that refers to itself, is als symmetrical, so you probably want to turn that off, since if a is a student of b, then b is not per se a student of a. You can do that by specifying symmetrical=False [Django-doc]:
class User(AbstractUser):
teacher_or_student = models.CharField(max_length=100)
mobile_number = models.CharField(max_length=100)
grade = models.CharField(max_length=100)
laptop_yes_or = models.CharField(max_length=100)
students = models.ManyToManyField(
'self',
symmetrical=False,
related_name='teachers'
)
Related
In this quiz game, I'm trying to filter the questions of a particular course.
models.py
class Course(models.Model):
course_name = models.CharField(max_length=50)
date_created = models.DateTimeField(auto_now_add=True)
class Quiz(models.Model):
course_name = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='quiz_course')
question = models.TextField(max_length=100)
class Choice(models.Model):
question = models.ForeignKey(Quiz, on_delete=models.CASCADE, related_name="choice_question")
choice = models.CharField(max_length=100)
is_true = models.BooleanField("This is Correct Answer", default=False)
class Quizgame(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
total_score = models.DecimalField("Total score", default=0, decimal_places=2, max_digits=6)
start_time = models.DateTimeField(auto_now_add=True)
finish_time = models.DateTimeField(null=True)
def get_new_question(self,course_id):
used_question = AttemptedQuestion.objects.filter(quiz_profile=self).values_list('question__id',flat=True)
remaining_questions = Quiz.objects.exclude(id__in=used_question)
if not remaining_questions.exists():
return
return random.choice(remaining_questions)
def create_attempt(self, question):
attempted_question = AttemptedQuestion(question=question, quiz_profile=self)
attempted_question.save()
class AttemptedQuestion(models.Model):
quiz_profile = models.ForeignKey(Quizgame, on_delete=models.CASCADE, related_name='attempt')
question = models.ForeignKey(Quiz, on_delete=models.CASCADE)
choice = models.ForeignKey(Choice, on_delete=models.CASCADE, null=True)
is_true = models.BooleanField(default=False)
In above where in class Quizgame I filter the questions in get_new_question method here I passed an course_id as an argument by I don't know how to filter out with the course_id for the particular course questions..
If you are trying to link a question to a course, I can't see a ForeignKey related to a Course object in your AttemptedQuestion class. You should add
class AttemptedQuestion(models.Model):
# ...
course = models.ForeignKey(Course, on_delete=models.CASCADE, null=True)
and then you can simply filter by
qs = AttemptedQuestion.objects.filter(course=course_id)
Before answering your question there is a simple tip that will help you raise the readability of your code.
If you're creating FK to a model named Course, name the field course. "course_name" is implying we will get a name in that field.
To access all the Quiz instances by course_id variable, you can use the __ operator in filter() method like this:
Quiz.objects.filter(course_name__id=course_id)
Note the double underscore __ after the "course_name". What this does is telling Django:
"Filter Quiz where course_name's id is equal to 'course_id'".
models.py
class Add_category(models.Model):
Category = models.CharField(max_length=100)
Image = models.ImageField()
MetaKeyword = models.CharField(max_length=100)
MetaDesc = models.CharField(max_length=100)
def __str__(self):
return self.Category
In this, I have tried to add city field and choices must come in this
field by the help of Add_category model but it fails.
class Make_Invoice(models.Model):
Order_no = models.IntegerField()
Invoice_no = models.IntegerField()
Product_name = models.CharField(max_length=100)
Product_Id = models.IntegerField()
Quantity = models.IntegerField()
City = models.CharField(max_length=100, choices = Add_category.Category, default='Select')
Why even use City as a as a CharField? As far as I see it should be a ForeignKey - ManyToOne or even ManyToMany relation.
Check it in the documentation:
https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_one/
https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_many/
Use a ForeignKey
City = models.ForeignKey('Add_category', on_delete=models.PROTECT)
In Django there are field types called ForeignKey and OneToMany/OneToOne, I was wondering would I use ForeignKey or the relationship type as the field type in this scenario? User to Profile has been identified as OneToOne but I'm unsure about the others.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
fullname = models.CharField(max_length=100)
dob = models.DateField()
address = models.TextField()
city = models.CharField(max_length=100)
profilephoto = models.ImageField(default='default_profile.jpg', upload_to='reviewApp/static/profile_images')
class Product(models.Model):
name = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
category = models.CharField(max_length=100)
releasedate = models.DateField()
description = models.TextField()
productphoto = models.ImageField(default='default_product.jpg', upload_to='reviewApp/static/product_images')
class Review(models.Model):
product = models.ForeignKey(Product)
profile = models.ForeignKey(Profile)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = model.PositiveSmallIntegerField(default=1, validators = [MinValueValidator(1), MaxValueValidator(5)])
reviewtext = models.TextField()
postdate = models.DateTimeField(auto_now_add=True)
lastmodified = models.DateTimeField(auto_now=True)
So from what I see here, it seems to be good if the following is what you want:
User can have only one profile and one Profile is related to only one user.
a Profile can make multiple Review but a Review belongs to only one profile.
A Product can have multiple Review but a Review is specific to one Product.
Be carefull to define the on_delete argument for your foreign keys depending of what you want to keep in your database after a delete.
More info from the doc : https://docs.djangoproject.com/fr/2.2/ref/models/fields/#arguments
Is there any way I can set through_field to an intermediatory models's nested field,
Just for an example:
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('assignee__group', 'person'),
)
class GroupLeader(models.Model)
identity = models.ForeignKey(Person)
group = models.ForeignKey(Group)
#more fields
class Membership(models.Model):
assignee = models.ForeignKey(GroupLeader)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
# more fields
I tried doing it but I am getting an error:
The intermediary model 'Membership' has no field 'assignee__group'
NOTE: The above is just an example, just in case such a situation is encountered.
Your group leader should NOT be part of the M2M relation, this is just a metadata. So just add group into the Membership class.
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
)
class GroupLeaders(models.Model)
identity = models.ForeignKey(Person)
group = models.ForeignKey(Group)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
assignee = models.ForeignKey(GroupLeaders)
or you can even completely strip out the GroupLeaders class
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
leader = models.ForeignKey(Person, on_delete=models.CASCADE,
related_name="leading_memberships",
)
I've tried reading the docs and previous answers to this question without much luck.
I've got a bunch of student-course registrations and I'd like to see some of those selected registrations in conjunction with some of the attributes of the students. No luck so far...I'd request your advice!
Here's the model:
class Student(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
netID = models.CharField(max_length=8)
class Registration(models.Model):
student = models.ForeignKey(Student)
course = models.ForeignKey(Course)
attendance_M = models.BooleanField(default=False)
attendance_Tu = models.BooleanField(default=False)
and here is the tables.py:
class AttendanceTable(tables.Table):
netID = tables.Column(accessor='Student.netID')
first = tables.Column(accessor='Student.first_name')
last = tables.Column(accessor='Student.last_name')
class Meta:
model = Registration
attrs = {"class": "paleblue"}
fields = ('attendance_M', 'attendance_Tu',)
sequence = ('netID', 'first', 'last', 'attendance_M', 'attendance_Tu',)
While I'm getting data on the attendance values, there's nothing from the student foreign columns.
netID First Last Attendance M Attendance Tu
— — — ✔ ✘
And it's the same deal if I start the Table with model = Student and use accessors against the Registration table, it's the same deal.
I feel like I'm missing something very conceptual and crucial -- please guide me!
The model name in the accessor parameter of the column should be lowercase.
Use accessor='student.netID' instead of accessor='Student.netID'.
When using the accessor parameter, you have to use the field name stated in the Model that has the foreign key, and then select which field from that table you want to use.
So, for these models:
#models.py
class Description_M(models.Model):
id_hash = models.CharField(db_column='Id_hash', primary_key=True, max_length=22)
description = models.CharField(db_column='Description', max_length=255, blank=True, null=True)
class GeoCodes(models.Model):
geo = models.CharField(db_column='Geo', primary_key=True, max_length=5)
city_name = models.CharField(db_column='City', max_length=150, blank=True, null=True)
class RefSources(models.Model):
id_source = models.IntegerField(db_column='Id_source', primary_key=True,)
source_name = models.CharField(db_column='Source', max_length=150, blank=True, null=True)
class Price(models.Model):
id_hash = models.ForeignKey(Description_M, models.DO_NOTHING, db_column='Id_hash')
date= models.ForeignKey(DateTime, models.DO_NOTHING, db_column='Date')
geo = models.ForeignKey(GeoCodes, models.DO_NOTHING, db_column='Geo')
id_source = models.ForeignKey(RefSources, models.DO_NOTHING, db_column='Id_source') # Field name made lowercase.
price = models.FloatField(db_column='Price',primary_key=True, unique=False,default=None)
When using the foreign key to pull fields from that table, you have to:
class price_table(tables.Table):
description = tables.Column(accessor = 'id_hash.description')
city = tables.Column(accessor = 'geo.city_name')
source = tables.Column(accessor = 'id_source.source_name')
class Meta:
model = Price
fields = ['date','price']
sequence = ['description ','date','city ','source','price']
template_name = 'django_tables2/bootstrap.html'