Django - Objects for business hours - django

I'm trying to modelize business hours for a week of a company. Here is my attempt:
class Company(models.Model):
name = models.CharField(max_length=100)
logo = models.FileField(upload_to='company_logos')
mon_start = models.TimeField()
mon_end = models.TimeField()
tue_start = models.TimeField()
tue_end = models.TimeField()
wed_start = models.TimeField()
wed_end = models.TimeField()
thu_start = models.TimeField()
thu_end = models.TimeField()
fri_start = models.TimeField()
fri_end = models.TimeField()
sat_start = models.TimeField()
sat_end = models.TimeField()
sun_start = models.TimeField(blank=True)
sun_end = models.TimeField(blank=True)
Does this seem correct ?
Isn't there a more dynamic way to define it ?
Can I easily validate each day (on a form) ?

From #lyapun suggestion, an acceptable solution for me would be:
WEEKDAYS = [
(1, _("Monday")),
(2, _("Tuesday")),
(3, _("Wednesday")),
(4, _("Thursday")),
(5, _("Friday")),
(6, _("Saturday")),
(7, _("Sunday")),
]
class Company(models.Model):
name = models.CharField(
max_length=100
)
logo = models.FileField(
upload_to='company_logos'
)
class OpeningHours(models.Model):
store = models.ForeignKey(
Company
)
weekday = models.IntegerField(
choices=WEEKDAYS,
unique=True
)
from_hour = models.TimeField()
to_hour = models.TimeField()

Related

Django Filter and Sum Value depends on different model

_Hi, guys! I'm trying to sum times for users for each Month(Mission), like this:
times = goal.time_set.filter(day__year=today.year, day__month=today.month)
Then I will sum:
for time in times:
total_min[member_number] = total_min[member_number] + time.value
But it calculates for current Month(Mission).
I want to calculate time depends on object model Mission. Model Mission:
class Mission(models.Model):
name = models.CharField(max_length=200, default='')
description = models.TextField(default='')
add_info = models.TextField(default='', blank=True)
theme = models.ImageField(upload_to='themes/', default='themes/default.png')
date_created = models.DateTimeField(null=True)
date_finished = models.DateTimeField(null=True, blank=True)
Like this I think:
times = goal.time_set.filter(day__year=mission.date_created.year, day__month=mission.month_created.month)
How can I achieve it?
upd. Goal model:
class Goal(models.Model):
STATUS = (
('in progress', 'in progress'),
('completed', 'completed'),
('failed', 'failed')
)
id_ninja = models.ForeignKey(Ninja, null=True, on_delete=models.SET_NULL)
id_user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
name = models.CharField(max_length=150, default='')
description = models.TextField(default='')
date_created = models.DateTimeField(null=True)
status = models.CharField(max_length=20, choices=STATUS, default='in progress')
I solved the problem in my way.
mission_year = mission.date_created.strftime('%Y')
mission_month = mission.date_created.strftime('%m')
times = goal.time_set.filter(day__year__gte=mission_year, day__month__gte=mission_month)

Getting Count Result With Multiple Conditions

I have models named Class, StudentList, Child, TakingQuiz and TakingQuizAnswer. Students can take exams. In this case, when they start the exam, data is added to the 'TakingQuiz' table. With each new answer, the answers are also recorded in the TakingQuizAnswer table.
The result I want to reach -> The question with the most mistakes in the exams solved by the students in a class.
I tried to use Count for this. I'm filtering answer_is_correct to False but that is insufficient. I also need to filter this data for the question column. So I need to get rows where both question and answer_is_correct = False columns are the same and return the first few most repetitive data as results.
I always get a general result in my experiments. I can't include rows where the question column is the same. How can I access the questions with the most mistakes in exams solved by students studying in a class?
Serializer
class ClassSerializerReport(ModelSerializer):
instructor = InstructorSerializerReport(source="instructor.user")
students = StudenListSerializerReport(many=True,
source="student_list_class")
max_incorrect_question = serializers.SerializerMethodField()
class Meta:
model = Class
exclude = [
"created_at",
"updated_at",
"school",
]
def get_max_incorrect_question(self, obj):
data = Class.objects.filter(id = obj.id).values('student_list_class__child__child_taking_quiz__taking_quizes').annotate(res = Count('student_list_class__child__child_taking_quiz__taking_quizes__question', filter = Q(student_list_class__child__child_taking_quiz__taking_quizes__answer_is_correct = False)))
print(data)
return {"question_id" : "I couldn't access that result yet."}
Related Models
class Class(AbstractSchoolBaseModel):
school = models.ForeignKey(
"school.School",
on_delete=models.CASCADE,
related_name="classes_school",
)
instructor = models.ForeignKey(
"account.InstructorProfile",
on_delete=models.CASCADE,
related_name="instructors_school",
)
name = models.CharField(
max_length=50,
)
grade = models.IntegerField(
)
class StudentList(AbstractSchoolBaseModel):
school_class = models.ForeignKey(
"school.Class",
on_delete=models.CASCADE,
related_name="student_list_class",
)
child = models.ForeignKey(
"account.ChildProfile",
on_delete=models.CASCADE,
related_name="student_list_children",
)
class ChildProfile(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
primary_key=True,
related_name="user_child")
city = models.ForeignKey(
"country.City",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="city_child_profiles")
hobbies = models.CharField(
max_length=500,
null=True,
blank=True,
)
class TakingQuiz(AbstractQuizBaseModel):
quiz = models.ForeignKey("quiz.Quiz", on_delete=models.DO_NOTHING, related_name="quiz_taking_quiz")
child = models.ForeignKey("account.ChildProfile", on_delete=models.CASCADE, related_name = "child_taking_quiz")
title = models.CharField(max_length=150, editable=False, default="-")
total_point = models.PositiveIntegerField(default=0)
class TakingQuizAnswer(AbstractQuizBaseModel):
taking_quiz = models.ForeignKey("quiz.TakingQuiz", on_delete=models.CASCADE, related_name="taking_quizes")
question = models.ForeignKey("quiz.Question", on_delete=models.DO_NOTHING, related_name="question_taking_quiz"e)
answer = models.ForeignKey("quiz.Answer", on_delete= models.DO_NOTHING, related_name="answer_taking_quiz")
taking_quiz_title = models.TextField(editable=False, null=True, blank=True)
question_text = models.TextField(editable=False, null=True, blank=True)
question_topic_content = models.TextField(editable=False, null=True, blank=True)
answer_text = models.TextField(editable=False, null=True, blank=True)
answer_is_correct = models.BooleanField(editable=False, null=True, blank=True)
class Quiz(AbstractQuizBaseModel):
ENABLED_CHOICES = (
(True, _("Active")),
(False, _("Not Active")),
)
book = models.ForeignKey("book.Book", on_delete= models.CASCADE, related_name="book_quiz")
title = models.CharField(max_length=150)
enabled = models.BooleanField(choices=ENABLED_CHOICES, default=False)
class Question(AbstractQuizBaseModel):
quiz = models.ForeignKey("quiz.Quiz", on_delete=models.DO_NOTHING, related_name="question_quiz")
question = models.CharField(max_length=500)
topic = models.CharField(max_length=500)
class Answer(AbstractQuizBaseModel):
IS_CORRECT_CHOICES = (
(True, _("Correct Answer")),
(False, _("Wrong Answer"))
)
question = models.ForeignKey("quiz.Question", on_delete=models.CASCADE, related_name = "question_answer")
answer = models.CharField(max_length=500)
is_correct = models.BooleanField(choices=IS_CORRECT_CHOICES, default=False)

How to create an object of model A out of 2 random objects of model B in Django?

I'm trying to create an app that meets two random users in Django.
my question is how to create an object Meeting out of 2 random users from my User model,
I want something like a for loop so that every 2 users in my database have a meeting!
ps: I have only one day left to submit my work I will be so thankful if u help me
this is my code so far:
def createMeeting():
user_p = get_user_model()
users = user_p.objects.all()
all_users = users.exclude(username="Admin")
n = all_users.count()
for k in range(math.floor(n/2)):
for user in all_users:
freedate = FreeDate.objects.filter(user=user)
starreds = user.userprofile.desired_user.all()
matched_user = User
if freedate:
if starreds:
for u in starreds:
u_freedate = FreeDate.objects.filter(user=u.user)
for dates in freedate:
for matchdates in u_freedate:
if dates.FreeTime == matchdates.FreeTime and dates.FreeDay == matchdates.FreeDay:
matched_user = u.user
else:
for u in users:
u_freedate = FreeDate.objects.filter(user = u)
for dates in freedate:
for matchdates in u_freedate:
if dates.FreeTime == matchdates.FreeTime and dates.FreeDay == matchdates.FreeDay:
matched_user = u
if matched_user and matched_user != user and not(Meeting.objects.filter(user1=user, user2=matched_user) | Meeting.objects.filter(user1=matched_user, user2=user)):
Meeting.objects.create(user1=user, user2=matched_user)`
it creates only one Meeting object and i'm getting this error:
TypeError: Field 'id' expected a number but got <class 'django.contrib.auth.models.User'>.
This is my models.py :
class UserProfile(models.Model):
GENDER=(
('Female','Female'),
('Male','Male'),
('Others', 'Others'),
)
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
birthdate = models.DateTimeField(default=timezone.now, null=True)
phone = models.CharField(max_length=200, null=True)
age = models.IntegerField(null=True, default=18)
years_of_experience = models.IntegerField(null=True, default=5)
job_title = models.CharField(max_length=200, null=True)
gender = models.CharField(max_length=200, null=True, choices=GENDER)
profile_image = models.ImageField(null=True, blank=True)
about = models.TextField(null=True)
desired_user = models.ManyToManyField("self")
skill = models.ManyToManyField("Skill")
`class Meeting(models.Model):
STATE_CHOICES = [
('Accepte', 'Accepte'),
('Deny', 'Deny'),
]
RATE_MEETING = [
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5'),
]
user1 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user1', null=True)
user2 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user2', null=True)
state1 = models.CharField(max_length=200, null=True, choices=STATE_CHOICES)
state2 = models.CharField(max_length=200, null=True, choices=STATE_CHOICES)
text1 = models.TextField(max_length=3000, null=True, blank=True)
text2 = models.TextField(max_length=3000, null=True, blank=True)
rate1 = models.PositiveSmallIntegerField(choices=RATE_MEETING, null=True, blank=True)
rate2 = models.PositiveSmallIntegerField(choices=RATE_MEETING, null=True, blank=True)
meeeting_place = models.ForeignKey(MeetingPlace, on_delete=models.CASCADE, null=True)`
I can't decipher what you're doing there, but:
for k in range(math.floor(n/2)):
for user in all_users:
freedate = FreeDate.objects.filter(user=user)
starreds = user.userprofile.desired_user.all()
matched_user = User # this is the line that's causing the error. Need an User instance, not the User class.
if freedate:

Django link multiple table

I have four models as follows:
class deals_view(models.Model):
deal = models.ForeignKey(dealsModel, on_delete=models.CASCADE, related_name='deal_view')
client = models.ForeignKey(client_profileModel, on_delete=models.CASCADE)
client_ip = models.GenericIPAddressField(protocol='both')
date_added = models.DateField(auto_now_add=True)
class client_profile(models.Model):
GENDER_NAME = (
('M', 'Male'),
('F', 'Female'),
('O', 'Others')
)
user = models.ForeignKey(User, unique=True, on_delete=models.CASCADE)
gender = models.CharField(max_length=1, choices=GENDER_NAME, null=True)
address = models.CharField(max_length=100, null=True)
dob = models.DateField(null=True)
class deals(models.Model):
GENDER_NAME = (
('M', 'Male'),
('F', 'Female'),
('O', 'Others'),
('A', 'All'),
)
AGE_RANGE = (
('A1', '18-25'),
('A2', '25-40'),
('A3', '40-55'),
('A4', '55-100'),
('A5', '18-100'),
('AL', '13-100'),
('T1', '13-18')
)
store = models.ForeignKey(storesModel, on_delete=models.CASCADE, related_name='deals_store')
title = models.CharField(max_length=30)
description = models.CharField(max_length=160)
price = models.DecimalField(max_digits=6, decimal_places=2)
category = models.ForeignKey(categoriesModel, on_delete=models.PROTECT)
targeted_gender = models.CharField(max_length=1, choices=GENDER_NAME)
targeted_age = models.CharField(max_length=2, choices=AGE_RANGE)
is_active = models.BooleanField(default=False)
created_date = models.DateField(auto_now_add=True)
expiry_date = models.DateField(default=(dt.now() + td(days=30)))
class stores(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=50, unique=True)
about = models.CharField(max_length=300)
company_name = models.CharField(max_length=100)
I want to list all deals for the current month and its corresponding number of views per gender.
so far I've tried the following; i can get all the info but it seems i have multiple hits of the database:
self.storeObj = storesModel.objects.prefetch_related('deals_store').get(id=storeid)
self.deals_store = self.storeObj.deals_store
segmentedInfo = self.deals_store.all().prefetch_related('deal_view').filter(deal_view__date_added__range=((datetime.today() - timedelta(days=30)), datetime.now())).distinct()
for seg in segmentedInfo:
for x in seg.deal_view.select_related('client').distinct():
print(x.client.gender)
Is there any way i can optimise my queries to get the number of views per gender for a deal of a specific store?
Yes, we can do some filtering in the related client_profile model, and then use a .annotate(..) to count the number of distinct ids.
from django.db.models import Count
client_profile.objects.filter(
deals_view__deal__store_id=storeid,
deals_view__date_added__range=(datetime.today()-timedelta(days=30), datetime.now())
).values('gender').annotate(
n=Count('id', distinct=True)
).order_by('gender')
This will result in a QuerySet that contains dictionaries with the gender, and the number of client_profiles, like:
<QuerySet [
{'gender': 'M', 'n': 1425},
{'gender': 'M', 'n': 1302},
{'gender': 'O', 'n': 173}
]>
If there are no client_profiles with a given gender that have seen the deal, then it is not part of the QuerySet.

Custom Django Form

I'm trying to make a custom backend for my system and I've hit a bit of a snag....I want to give users the ability to add new makes/models/series that are not already in the system via a form. I'm wondering how I'll go about this...my models look as below:
class Manufacturer(models.Model):
MANUFACTURER_POPULARITY_CHOICES = (
('1', 'Primary'),
('2', 'Secondary'),
('3', 'Tertiary'),
)
manufacturer = models.CharField(max_length=15, blank=False)
date_added = models.DateField()
manufacturer_popularity = models.CharField(max_length=1,
choices=MANUFACTURER_POPULARITY_CHOICES)
def __unicode__(self):
return self.manufacturer
class Model(models.Model):
model = models.CharField(max_length=20, blank=False)
manufacturer = models.ForeignKey(Manufacturer)
date_added = models.DateField()
def __unicode__(self):
name = ''+str(self.manufacturer)+" "+str(self.model)
return name
class Series(models.Model):
series = models.CharField(max_length=20, blank=True, null=True)
model = models.ForeignKey(Model)
date_added = models.DateField()
def __unicode__(self):
name = str(self.model)+" "+str(self.series)
return name
class Engine(models.Model):
ENGINE_TYPE_CHOICES = (
('H', 'H'),
('I', 'I'),
('R', 'R'),
('V', 'V'),
('W', 'W'),
)
FUEL_TYPE_CHOICES = (
('G', 'Gas'),
('D', 'Diesel'),
)
size = models.DecimalField(max_digits=2, decimal_places=1)
type = models.CharField(max_length=1, choices=ENGINE_TYPE_CHOICES)
cylinders = models.PositiveSmallIntegerField()
spec = models.CharField(max_length=20, blank=True, null=True)
fuel_type = models.CharField(max_length=1, choices=FUEL_TYPE_CHOICES)
class CommonVehicle(models.Model):
year = models.ForeignKey(Year)
series = models.ForeignKey(Series)
engine = models.ForeignKey(Engine)
body_style = models.ForeignKey(BodyStyle)
transmission = models.ForeignKey(Transmission)
speeds = models.PositiveSmallIntegerField()
drive_train = models.ForeignKey(DriveTrain)
horse_power = models.PositiveSmallIntegerField()
litre_100km_city = models.DecimalField(max_digits=3, decimal_places=1)
litre_100km_hwy = models.DecimalField(max_digits=3, decimal_places=1)
def __unicode__(self):
name = ''+str(self.year)+" "+str(self.series)
return name
This seems to be a fairly standard job for a django model form. I would recommend following the documentation at http://docs.djangoproject.com/en/dev/topics/forms/modelforms/. There are detailed instructions there on how to create a form from a model and then save the returned submission to the database.