Django Attribute Error - 'ForwardManyToOneDescriptor' object has no attribute 'courses' - python

I have created different models and in the Division model I am taking reference of many models and their primary key is referenced as a foreign key in Division Model. I have declared courses as a model attribute in the Batch Model.
This is my models.py file
class lab_load(models.Model):
lab_code = models.CharField(max_length=10,null=True)
subject_name = models.CharField(max_length=100,null=True)
subject_abv = models.CharField(max_length=10,null=True)
lab_load = models.IntegerField(null=True)
semester = models.IntegerField(null=True)
max_numb_students = models.CharField(max_length=65,null=True)
instructors = models.ManyToManyField(Instructor)
def __str__(self):
return f'{self.lab_code} {self.subject_name} {self.subject_abv}'
class Batch(models.Model):
bat_name = models.CharField(max_length=50)
courses = models.ManyToManyField(lab_load)
#property
def get_courses(self):
return self.courses
def __str__(self):
return self.bat_name
class Division(models.Model):
division_id = models.CharField(max_length=25, primary_key=True)
batch = models.ForeignKey(Batch, on_delete=models.CASCADE,blank=True, null=True)
num_lab_in_week = models.IntegerField(default=0)
course = models.ForeignKey(lab_load, on_delete=models.CASCADE, blank=True, null=True)
lab_time = models.ForeignKey(LabTime, on_delete=models.CASCADE, blank=True, null=True)
room = models.ForeignKey(LabRoom,on_delete=models.CASCADE, blank=True, null=True)
instructor = models.ForeignKey(Instructor, on_delete=models.CASCADE, blank=True, null=True)
def set_labroom(self, labroom):
division = Division.objects.get(pk = self.division_id)
division.room = labroom
division.save()
def set_labTime(self, labTime):
division = Division.objects.get(pk = self.division_id)
division.lab_time = labTime
division.save()
def set_instructor(self, instructor):
division = Division.objects.get(pk=self.division_id)
division.instructor = instructor
division.save()
My views.py file
class Data:
def __init__(self):
self._rooms = Room.objects.all()
self._meetingTimes = MeetingTime.objects.all()
self._instructors = Instructor.objects.all()
self._courses = Course.objects.all()
self._depts = Department.objects.all()
self._labrooms = LabRoom.objects.all()
self._labTimes = LabTime.objects.all()
self._labcourses = lab_load.objects.all()
self._bats = Batch.objects.all()
def get_rooms(self): return self._rooms
def get_labs(self): return self._labs
def get_labrooms(self): return self._labrooms
def get_instructors(self): return self._instructors
def get_courses(self): return self._courses
def get_depts(self): return self._depts
def get_labcourses(self): return self._labcourses
def get_bats(self): return self._bats
def get_meetingTimes(self): return self._meetingTimes
def get_labTimes(self): return self._labTimes
Under different class: Created class LabSchedule under that I have created function initialize.
def initialize(self):
divisions = Division.objects.all()
for division in divisions:
bat = Division.batch
n = division.num_lab_in_week
if n <= len(LabTime.objects.all()):
labcourses = bat.courses.all() <------ Error in this line ------->
for labcourse in labcourses:
for i in range(n // len(labcourses)):
crs_inst = labcourse.instructors.all()
newClass = Classlab(self._classNumb, bat, division.division_id, labcourse)
self._classNumb += 1
newClass.set_labTime(data.get_labTimes()[rnd.randrange(0, len(LabTime.objects.all()))])
newClass.set_labroom(data.get_labrooms()[rnd.randrange(0, len(data.get_labrooms()))])
newClass.set_instructor(crs_inst[rnd.randrange(0, len(crs_inst))])
self._classes.append(newClass)
else:
n = len(LabTime.objects.all())
labcourses = bat.courses.all()
for labcourse in labcourses:
for i in range(n // len(labcourses)):
crs_inst = labcourse.instructors.all()
newClass = Classlab(self._classNumb, bat, division.division_id, labcourse)
self._classNumb += 1
newClass.set_labTime(data.get_labTimes()[rnd.randrange(0, len(LabTime.objects.all()))])
newClass.set_labroom(data.get_labrooms()[rnd.randrange(0, len(data.get_labrooms()))])
newClass.set_instructor(crs_inst[rnd.randrange(0, len(crs_inst))])
self._classes.append(newClass)
return self
I am using a genetic algorithm to schedule classes and labs.
Can anyone solve my error it will be helpful, Thank You.

Related

Attribute Error: str object - has no attribute days. Attempting to migrate my model

Have two models that I am attempting to override the save functions (parent and Child).
the models look like this:
from django.db import models
from django.urls import reverse
from datetime import datetime, timedelta
class Program(models.Model):
air_date = models.DateField(default="0000-00-00")
air_time = models.TimeField(default="00:00:00")
service = models.CharField(max_length=10)
block_time = models.TimeField(default="00:00:00")
block_time_delta = models.DurationField(default="00:00:00")
running_time = models.TimeField(default="00:00:00")
running_time_delta = models.DurationField(default="00:00:00")
remaining_time = models.TimeField(default="00:00:00")
remaining_time_delta = models.DurationField(default="00:00:00")
title = models.CharField(max_length=190)
locked_flag = models.BooleanField(default=False)
deleted_flag = models.BooleanField(default=False)
library = models.CharField(null=True,max_length=190,blank=True)
mc = models.CharField(null=True,max_length=64)
producer = models.CharField(null=True,max_length=64)
editor = models.CharField(null=True,max_length=64)
remarks = models.TextField(null=True,blank=True)
audit_time = models.DateTimeField(null=True)
audit_user = models.CharField(null=True,max_length=32)
def calculate_time(self):
total_run_time_delta = timedelta(minutes=0)
hold_remaining_delta = models.DurationField()
for segs in self.segments.all():
total_run_time_delta += segs.length_time_delta
self.running_time_delta = total_run_time_delta
self.running_time = f"{self.running_time_delta}"
self.remaining_time_delta = self.block_time_delta - total_run_time_delta
self.remaining_time = f"{abs(self.remaining_time_delta)}"
def save(self, *args, **kwargs):
self.calculate_time()
super().save(*args,**kwargs)
def __str__(self):
return f"{self.pk} : {self.title}"
def get_absolute_url(self):
return reverse('program_detail', args=[str(self.id)])
#return reverse('program-update', kwargs={'pk': self.pk})
class Segment(models.Model):
program_id = models.ForeignKey(Program,
on_delete=models.CASCADE,
related_name='segments', #new link to Program
)
sequence_number = models.DecimalField(decimal_places=2,max_digits=6,default="0.00")
title = models.CharField(max_length=190)
bridge_flag = models.BooleanField(default=False)
length_time = models.TimeField(null=True,default=None, blank=True)
length_time_delta = models.DurationField(default="00:00:00")
author = models.CharField(max_length=64,null=True,default=None,blank=True)
voice = models.CharField(max_length=64,null=True,default=None,blank=True)
library = models.CharField(max_length=190,null=True,default=None,blank=True)
summary = models.TextField()
audit_time = models.DateTimeField(null=True)
audit_user = models.CharField(null=True,max_length=32)
def save( self, *args, **kwargs):
program = Program.object.get(id=self.program_id)
super().save(*args,**kwargs)
program.save()
def __str__(self):
return self.author
After python manage.py make migrations (which works by the way),
I try to migrate and get this...
cmd$ python manage.py migrate
( ... bunch of errors ... )
File "/Users/toadyb/.local/share/virtualenvs/trackx_proj-eoegj60O/lib/python3.9/site-packages/django/utils/duration.py", line 44, in duration_microseconds
return (24 * 60 * 60 * delta.days + delta.seconds) * 1000000 + delta.microseconds
AttributeError: 'str' object has no attribute 'days'
Anybody know why I am getting this?
Thanks
Default value for DateField/TimeField/DateTimeField should be instance of datetime datetime or date or time. I think in some cases you are trying to get default value of that fields, and from default you are getting string, not datetime object

Why am I getting core.Model.none?

I'm working on a django based backend.
I have a Submentor model. This model is going to have a list of names associated with it. So, I made a model called List. they both have a manytoMany relationship. Now, I made another model called names. This has a ManytoMany relationship with List. The list will have many names. Each Submentor will have one List each.
After coding when I try to add a value in The list from admin console I get core.Name.none instead of the name in my Submentors list.
What am I doing wrong?
code of models :-
class Names(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE,blank=True,null=True)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class SAccepted_list(models.Model):
saccepted_name = models.ManyToManyField(Names,blank =True, related_name='saccepted_name')
def __str__(self):
return str(self.saccepted_name)
class SPending_list(models.Model):
spending_name = models.ManyToManyField(Names,blank =True, related_name='spending_name')
def __str__(self):
return str(self.spending_name)
class SRejected_list(models.Model):
srejected_name = models.ManyToManyField(Names,blank =True, related_name='srejected_name')
def __str__(self):
return str(self.srejected_name)
class SubMentor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
mentee_pref_count = models.IntegerField(default=3, verbose_name='Preferred mentee count')
rating = GenericRelation(Rating, related_query_name='Submentor')
skills = models.ManyToManyField(Skill, blank=True, related_name='subskills')
courses = models.ManyToManyField(Course, blank=True, related_name='subcourses')
projects = models.ManyToManyField(Project, blank=True, related_name='subprojects')
saccepted_list = models.ManyToManyField(SAccepted_list,blank=True,related_name='saccepted_list')
spending_list = models.ManyToManyField(SPending_list, blank=True,related_name='spending_list')
srejected_list = models.ManyToManyField(SRejected_list, blank=True,related_name='srejected_list')
def __str__(self):
return self.user.get_full_name()
def get_mentee_count(self, *args, **kwargs):
if self.trainees.exists():
return self.trainees.count()
else:
return 0
class Accepted_list(models.Model):
accepted_name = models.ManyToManyField(Names,blank =True, related_name='accepted_name')
# saccepted_name = models.ManyToManyField(Names,blank =True, related_name='saccepted_name')
def __str__(self):
return str(self.accepted_name)
class Pending_list(models.Model):
pending_name = models.ManyToManyField(Names,blank =True, related_name='pending_name')
# spending_name = models.ManyToManyField(Names,blank =True, related_name='spending_name')
def __str__(self):
return str(self.pending_name)
class Rejected_list(models.Model):
rejected_name = models.ManyToManyField(Names,blank =True, related_name='rejected_name')
# srejected_name = models.ManyToManyField(Names,blank =True, related_name='srejected_name')
def __str__(self):
return str(self.rejected_name)
class Mentor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
score = models.FloatField(default=0, blank=True, null=True)
mentee_pref_count = models.IntegerField(default=5, verbose_name='Preferred menteee count')
rating = GenericRelation(Rating, related_query_name='mentor')
skills = models.ManyToManyField(Skill, blank=True, related_name='skills')
accepted_list = models.ManyToManyField(Accepted_list,blank=True,related_name='accepted_list')
pending_list = models.ManyToManyField(Pending_list, blank=True,related_name='pending_list')
rejected_list = models.ManyToManyField(Rejected_list, blank=True,related_name='rejected_list')
def __str__(self):
return self.user.get_full_name()
def get_mentee_count(self, *args, **kwargs):
if self.trainees.exists():
return self.trainees.count()
else:
return 0
picture of me adding names direct through admin console:-
Thank you.
Ok, I solved my problem. It was wrong of me in the first place to use m2m and then another to make a list.
Instead I used only 1 m2m relationship with Lists and then made a property of them to be charfield. Now it's working properly.
Thanks :)

Django form initial pass a list to one attribute

I met an issue when I want to pass a list of value to one attribute during initial the form.
The whole process of what I am doing is:
1. User defines a number N.
2. I display N text field.
3. User fills in data and I store in the database.
4. User wants to modify the data -> which is the issue I have when. I want to initial the form with current data.
Here is my model.py
class PageComponent(models.Model):
componentName=models.CharField(max_length=50,null=True, verbose_name="Name")
type = models.ForeignKey(Type, on_delete=models.CASCADE)
user = models.ForeignKey(AS_User, on_delete=models.CASCADE, editable=False)
page = models.ForeignKey(CommunityPage, on_delete=models.CASCADE, editable=False)
STATUS = (
('a', 'Activated'),
('d', 'Deactivated'),
)
componentStatus=models.CharField(
max_length=1,
choices=STATUS,
blank=False,
default='d',
help_text='the current status of the page component', editable=False
)
textContent=models.TextField(max_length=10000, help_text="Enter a description for your component", null=True, blank=True)
photoContent=models.ImageField(upload_to=component_directory_path, null=True, blank=True, verbose_name="Photo")
videoContent=models.FileField(upload_to=component_directory_path, null=True, blank=True, verbose_name="Video")
def __str__(self):
return self.componentName
class PageComponent_SeasonalText(models.Model):
pageStextComponent = models.ForeignKey(PageComponent, on_delete=models.CASCADE)
seasonalText = models.CharField(max_length=10001)
Here is my form.py
class SeasonalTextForm(forms.Form):
componentName = forms.CharField(label=_('Enter title'),max_length=40)
def __init__(self, *args, **kwargs):
seasonTexts = kwargs.pop('extra')
super(SeasonalTextForm, self).__init__(*args, **kwargs)
# self.cleaned_data = {}
for i in range(0, seasonTexts):
field_name = 'seasonText_%s' % (i,)
self.fields[field_name] = forms.CharField(widget=forms.Textarea(attrs={'rows':10, 'cols':51}))
#set field label as placeholder for every field
for field in self.fields.values():
field.widget.attrs["placeholder"] = field.label
def clean(self):
seasonTexts = set()
i = 0
field_name = 'seasonText_%s' % (i,)
while self.cleaned_data.get(field_name):
seasonText = self.cleaned_data[field_name]
if seasonText in seasonTexts:
self.add_error(field_name, 'Duplicate')
else:
seasonTexts.add(seasonText)
i += 1
field_name='seasonText_%s' % (i,)
self.cleaned_data["seasonTexts"] = seasonTexts
def save(self):
for seasonalText in self.cleaned_data["seasonTexts"]:
PageComponent_SeasonalText.objects.create(pageStextComponent = PageComponent.pageStextComponent,seasonalText = seasonalText,)
Here is my view.py
def edit_stext(request, page_id, id):
page = get_object_or_404(CommunityPage, pk=page_id)
component = PageComponent.objects.get(id=id)
stext = PageComponent_SeasonalText.objects.filter(pageStextComponent=component)
numOfSeasons = page.numSeasons
if request.method == "POST":
stextEditor = SeasonalTextForm(request.POST, instance=stext, extra=numOfSeasons)
if stextEditor.is_valid():
stextEditor.save()
return HttpResponseRedirect(reverse('page', kwargs={'page_id' : page_id}))
else:
# stext1 = PageComponent_SeasonalText.objects.filter(pageStextComponent=component)
initial = {}
initial['componentName'] = component.componentName
for i in range(0,numOfSeasons):
st = stext[i].seasonalText
print(st)
initial['seasonalText_{}'.format(i)] = st
stextEditor = SeasonalTextForm(initial=initial, extra=numOfSeasons)
return render(request, 'editComponent_stext.html', {'stextEditor': stextEditor})
NB:
at the view.py, I have a print function to print the actual value of the attribute "seasonalText" and it is success. But it seems cannot be passed to the initial when I want to initial the form.
Thanks for all spending time to help me with this issue. Many thanks.
Screenshot for understanding:
print function gets the correct value
initialed form doesn't get the seasonalText value

Manager object has no attribute 'save'

In my serializers.py I have a OrderCreateSerializer:
class OrderCreateSerializer(ModelSerializer):
data_params = serializers.DictField() # 根据产品数据模型不同而异
class Meta:
model = Order
fields = (
"product_describe", # 产品描述 (购买xx产品 + 参数)
"billing_type", # 计费类型 ("包年包月")
"data_params", # 数据
)
def create(self, validated_data):
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
validated_data["order_num"] = generateOrderNum(userid=user.id)
validated_data["order_status"] = "未支付"
validated_data["order_status"] = "未支付"
data_dic = validated_data.pop("data_params") #
# data_dic["data"]["profile"]
validated_data["buytime"] = data_dic["data"]["buytime"]
validated_data["count"] = data_dic["data"]["count"]
validated_data["paytype"] = ""
validated_data["cost"] = ""
validated_data["account"] = user.account
return Order.objects.save(**validated_data) # this is the line 57
When I save the validated_data, it report the bellow error:
Manager object has no attribute 'save'
My Order model is like bellow, there is many fields in it :
class Order(models.Model):
"""
订单
"""
order_num = models.CharField(max_length=128, unique=True) # 订单编号
order_status = models.CharField(max_length=12) # 订单状态 "未支付", "已支付,未完成", "已完成", "已经删除","其他"
product_describe = models.TextField() # 产品描述
billing_type = models.CharField(max_length=16) # 计费类型
buytime = models.CharField(max_length=16) # 比如:1月 永久
count = models.IntegerField() # 购买数量
paytype = models.CharField(max_length=16) # 支付方式(支付包,微信,xxx)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00) # 费用(需要花费多少钱)
account = models.ForeignKey(to=Account) # 所属账户
ctime = models.DateTimeField(auto_now_add=True) # 创建时间
uptime = models.DateTimeField(auto_now=True) # 更新时间
def __str__(self):
return self.product_describe
def __unicode__(self):
return self.product_describe
I don't know why there is the Manager object here.
You're calling save on the manager (ie, objects)
return Order.objects.save(**validated_data)
You call save on models.
I assume you're trying to create the model, in which case you want create.
return Order.objects.create(**validated_data)
Order.objects is an instance of the Manager class. The save method is a method of the model class.
Try:Order(**validated_data).save()

How to filter records of ManyToManyField?

I have following Django models:
class TopicLabel(models.Model):
name = models.CharField(max_length=256)
order = models.IntegerField(null=True, blank=True)
topics = models.ManyToManyField(Topic, through='TopicLabelConnection')
class Topic(models.Model):
title = models.CharField(max_length=140)
visible = models.NullBooleanField(null=True, blank=True, default=False)
def __unicode__(self):
return self.title
class Meta:
verbose_name = _('topic')
verbose_name_plural = _('topics')
class TopicLabelConnection(models.Model):
topicId = models.ForeignKey(Topic, related_name='connection_topic')
labelId = models.ForeignKey(TopicLabel, related_name='connection_label')
def __unicode__(self):
return self.labelId.name + ' / ' + self.topicId.title
I want to create a method of TopicLabel, which will return to me all topics in the TopicLabel.topic collection, which have Topic.visible = True.
I want to program a Django equivalent of the following query:
SELECT *
FROM OPINIONS_TOPICLABELCONNECTION, OPINIONS_TOPIC
WHERE (OPINIONS_TOPICLABELCONNECTION.topicId_id = OPINIONS_TOPIC.id) AND
(OPINIONS_TOPICLABELCONNECTION.labelId_id = X) AND
(OPINIONS_TOPIC.visible = 1)
where X is the primary key of the topic label.
I tried following method definitions and they all failed:
1)
class TopicLabel(models.Model):
[...]
def getVisibleTopics():
return topics.filter(connection_topic__visible=True)
2)
class TopicLabel(models.Model):
[...]
def getVisibleTopics():
return topics.filter(visible=True)
3)
class TopicLabel(models.Model):
[...]
def getVisibleTopics():
return Topic.objects.filter(connection_label__visible=True).filter(connection_label__id=self.id)
4)
class TopicLabel(models.Model):
[...]
def getVisibleTopics():
return Topic.objects.filter(connection_label__visible=True).filter(connection_label__id=self.id)
5)
class TopicLabel(models.Model):
[...]
def getVisibleTopics():
return topics.filter(connection_topicId__visible=True)
What is the correct code?
First, you need to have self as the first parameter on a method. Then filter the topics. try this:
class TopicLabel(models.Model):
[...]
def getVisibleTopics(self):
return self.topics.filter(visible=True)
Also, is there a reason you are creating a custom through table? It doesn't look like you are adding any extra data to it.

Categories