How to design Django models? - python

This is my Django Models
class Course(models.Model):
course_name = models.CharField(max_length=100, blank=True)
def __str__(self):
return self.course_name
class Video(models.Model):
video_name = models.CharField(max_length=100, blank=True)
video_link = models.CharField(max_length=500, blank=True)
def __str__(self):
return self.video_name
class Unit(models.Model):
unit_name = models.CharField(max_length=100, blank=True)
videos = models.ManyToManyField(Video)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
def __str__(self):
return self.unit_name
class Blog(models.Model):
blog_name = models.CharField(max_length= 100)
def __str__(self):
return self.blog_name
Python Tutorial 2
Python Tutorial 1
I want my Python Tutorial 2 doesn't have a video list that Python Tutorial 1 has, but every unit in Python Tutorial 1 has the same video list, How I could modify my code to have that system?

Related

I need to run a query on django but I am unable to generate an algorithm

I have these models in Django
class Course(models.Model):
Title = models.CharField(max_length=200, unique=True)
Card_Title = models.CharField(max_length=200, default='Nothing')
Description = RichTextField(blank=True, null=True)
Course_Image = models.FileField(upload_to='CoursesImages')
Progress = models.IntegerField(blank=True, null=True)
date = models.DateField(default=timezone.now, blank=True)
def __str__(self):
return self.Title
class Lesson(models.Model):
Course_id = models.ForeignKey(Course, on_delete=models.CASCADE)
Number = models.IntegerField()
Title = models.CharField(max_length=200)
Completed = models.BooleanField(default=False, blank=True)
date = models.DateField(default=timezone.now, blank=True)
def __str__(self):
return self.Title + ' (' + str(self.Number) + ')'
class Topic(models.Model):
Title = models.CharField(max_length=100)
Topic = models.FileField()
Lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE)
Completed = models.BooleanField(default=False, blank=True)
date = models.DateField(default=timezone.now, blank=True)
def __str__(self):
return self.Title
How it works :
Every lesson will have one course
So we have many lessons in one course
And one topic can have one lesson
So we have many topics in one lesson
I need to figure out why the query is like this:
{'Lesson1':[Topic1,Topic2,Topic,3,Topic,4],'Lesson':[Topic1,Topic2,Topic,3,Topic,4],........}
Course ID, Relevant Lessons, and Topic will have to be fetched
ans = {}
lessons = course.lesson_set
for lesson in lessions:
ans[lession.title] = lesson.topic_set

AssertionError: First parameter to ForeignKey must be either a model, a model name, or the string 'self'

I just created a model like this :
from django.db import models
# Create your models here.
class Category:
title = models.CharField(max_length=50)
slug = models.CharField(max_length=200)
cat_image = models.ImageField(upload_to='images/')
def __str__(self):
return self.title
class Brand:
title = models.CharField(max_length=50)
slug = models.CharField(max_length=200)
brand_image = models.ImageField(upload_to='images/')
def __str__(self):
return self.title
class UOM:
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class Product_Images:
multi_images = models.ImageField(upload_to='images/')
class Product:
name = models.CharField(max_length=100)
slug = models.CharField(max_length=200)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
price = models.IntegerField(null=True, blank=True)
height = models.IntegerField(null=True, blank=True)
weight = models.IntegerField(null=True, blank=True)
length = models.IntegerField(null=True, blank=True)
color = models.IntegerField(null=True, blank=True)
stock = models.BooleanField()
SKU = models.CharField(max_length=150)
def __str__(self):
return self.name
class Customer:
phone_number = models.CharField(max_length=11)
first_name = models.CharField(max_length=10)
last_name = models.CharField(max_length=10)
email = models.CharField(max_length=20)
password = models.CharField(max_length=10)
def __str__(self):
return self.first_name
class Order:
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
invoice = models.CharField(max_length=16, null=True, blank=True)
phone = models.CharField(max_length=12)
address = models.CharField(max_length=150)
But facing this error dont have any idea why i am getting this kind of error. I cant even makemigrations if i delete some fields. It says no change detected but i changed some fields still getting this kind of error can some one solve this issue for me. and please explain why ia magetting this kind of error i cant find any problem here. I am also facing this no changes issue on my macos also. i am changing some fields still it says no changes detected .
Models in django haveto be like:
class ModelClass(models.Model):

django quiz app model for multiple choice questions

I am creating quiz app in django, my django model for questions is like this,
class Question(models.Model):
questions = models.CharField(max_length=50, unique=True)
choice1 = models.CharField(max_length=50, unique=True)
choice2 = models.CharField(max_length=50, unique=True)
choice3 = models.CharField(max_length=50, unique=True)
choice4 = models.CharField(max_length=50, unique=True)
correct_answer = models.CharField(max_length=50, unique=True)
is this fine or save the four options in postgres array or save the choices in separate table.
For a properly normalized relational database schema, you want a distinct Choice model with a foreign key on Question:
class Question(models.Model):
question = models.CharField(...)
class Choice(models.Model):
question = models.ForeignKey("Question", related_name="choices")
choice = modelsCharField("Choice", max_length=50)
position = models.IntegerField("position")
class Meta:
unique_together = [
# no duplicated choice per question
("question", "choice"),
# no duplicated position per question
("question", "position")
]
ordering = ("position",)
And then you can get at a Question's choices with myquestion.choices.all() (and get the question from a Choice with mychoice.question).
Note that this won't impose any limitation on the number of choices for a Question, not even mandates that a Question has at least one related Choice.
Unless you have a very compelling reason to do otherwise, a properly normalized schema is what you want when using a relational database (rdbms are much more than mere bitbuckets, they offer a lot of useful features - as long as you do have a proper schema, that is).
This tutorial shows it all https://medium.com/#nsjcorps/create-a-quiz-application-with-django-rest-framework-react-redux-part-one-f0fcae5103fd
This is the summary of it though:
from django.db import models
from django.contrib.auth.models import User
from django.template.defaultfilters import slugify
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
class Quiz(models.Model):
name = models.CharField(max_length=1000)
questions_count = models.IntegerField(default=0)
description = models.CharField(max_length=70)
created = models.DateTimeField(auto_now_add=True,null=True,blank=True)
slug = models.SlugField()
roll_out = models.BooleanField(default=False)
class Meta:
ordering = [‘created’,]
verbose_name_plural =”Quizzes”
def __str__(self):
return self.name
class Question(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
label = models.CharField(max_length=1000)
order = models.IntegerField(default=0)
def __str__(self):
return self.label
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
text = models.CharField(max_length=1000)
is_correct = models.BooleanField(default=False)
def __str__(self):
return self.text
class QuizTakers(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
correct_answers = models.IntegerField(default=0)
completed = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username
class Response(models.Model):
quiztaker = models.ForeignKey(QuizTakers, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
answer = models.ForeignKey(Answer,on_delete=models.CASCADE,null=True,blank=True)
def __str__(self):
return self.question.label
#receiver(post_save, sender=Quiz)
def set_default_quiz(sender, instance, created,**kwargs):
quiz = Quiz.objects.filter(id = instance.id)
quiz.update(questions_count=instance.question_set.filter(quiz=instance.pk).count())
#receiver(post_save, sender=Question)
def set_default(sender, instance, created,**kwargs):
quiz = Quiz.objects.filter(id = instance.quiz.id)
quiz.update(questions_count=instance.quiz.question_set.filter(quiz=instance.quiz.pk).count())
#receiver(pre_save, sender=Quiz)
def slugify_title(sender, instance, *args, **kwargs):
instance.slug = slugify(instance.name)
you can use arryfield if you are using postgres sql
class QuizMcqDetail(BaseModel):
title = models.CharField(max_length=255, null=True, blank=True)
time_limit = models.TimeField()
start_date = models.DateTimeField(null=True, blank=True)
end_date = models.DateTimeField(null=True, blank=True)
available_languages = models.ManyToManyField(QuizLanguage, related_name='available_language', blank=True)
question_count = models.PositiveIntegerField(default=10)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.title
class QuizMcqQuestion(BaseModel):
s_no = models.PositiveIntegerField()
quiz = models.ForeignKey(QuizMcqDetail, on_delete=models.CASCADE, related_name='quiz_mcq')
question_text = models.TextField(max_length=200)
options = ArrayField(models.CharField(max_length=200))
answer_position = ArrayField(models.IntegerField())
explanation = models.TextField(null=True)
language = models.ForeignKey(QuizLanguage, related_name='question_language', on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.question_text
class QuizMcqSelect(BaseModel):
quiz_question = models.ForeignKey(QuizMcqQuestion, related_name="select_quiz_mcq", on_delete=models.CASCADE)
user = models.ForeignKey(User, related_name="user_select_quiz_mcq", on_delete=models.CASCADE)
answer = models.BooleanField(default=False)
selected_answer = ArrayField(models.IntegerField())
def __str__(self):
return f"{self.quiz_question} {self.user} {self.answer}"
def save(self, *args, **kwargs):
if self.quiz_question.answer_position == self.selected_answer:
self.answer = True
else:
self.answer = False
super().save(*args, **kwargs)
The best way is:
ANSWER_CHOICES = (
("choice_1", "Answer_1"),
("choice_2", "Answer_2"),
("choice_3", "Answer_3"),
("choice_4", "Answer_4"),
("choice_5", "Answer_5"),
("choice_6", "Answer_6"),
)
class Question(models.Model):
questions = models.CharField
(
max_length=50,
unique=True,
choices=ANSWER_CHOICES
)
correct_answer = models.CharField(max_length=50, unique=True)

why am I getting column main_category.parent_cat_id does not exist

So every thing works fine in development but as soon as I do eb deploy this problem occurs again. I don't have related_cat in my code.
ProgrammingError at /admin/main/category/
column main_category.parent_cat_id does not exist
LINE 1: ...n_category"."author_id", "main_category"."image", "main_cate...
^
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
description = models.TextField(verbose_name=('community'))
author = models.ForeignKey(settings.AUTH_USER_MODEL)
image = models.ImageField(upload_to='images/', null=True, blank=True, verbose_name=('image'))
# parent_cat = models.ForeignKey('self', null=True, blank=True)
hotCat = models.BooleanField(default=False)
active = models.BooleanField(default=True)
sponsored = models.ForeignKey(Sponsored, null=True, blank=True)
objects = CategoryManager()
def __unicode__(self):
return self.name
def get_absolute_url(self):
return "/category/%s/" %self.name
def get_image_url(self):
return "%s%s" %(settings.MEDIA_URL, self.image)

order_by did't work after filtering by foreign key

I have a model like this
class Category(models.Model):
title = models.CharField(max_length=100, db_index=True)
slug = models.SlugField(max_length=100, db_index=True)
def __str__(self):
return "%s"%self.title
class Video(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
idlink = models.CharField(max_length=50)
posted = models.DateField(db_index=True, auto_now_add=True)
category = models.ForeignKey(Category)
def __str__(self):
return "%s"%self.title
And my views.py is
def list_video_cat(request, slug):
video = Video.objects.filter(category__slug=slug).order_by('-posted')
return render(request, 'category.html', {'videos':video})
I want to show my post new to old, but it seems to did not work at this situation. What should I do?
P/S the "duplicated post" does not solve my problem

Categories