django - adding a counter for every ManyToMany field added - django

i have these models:
#model.py
class Subject(models.Model):
name = models.CharField("Name",max_length=50, blank=True)
...
...
class Activity(models.Model):
label = models.CharField("Act. name",max_length=150)
price = models.DecimalField("price", max_digits=10, decimal_places=2,default=0)
count = models.IntegerField("Count", default=0)
def __unicode__(self):
return u"%s" % (self.label)
class Meta:
verbose_name_plural = "Activities"
class Invoice(models.Model):
subject = models.ForeignKey(Subject)
date = models.DateField(default=date.today())
activities = models.ManyToManyField(Activity)
....
....
while creating a new Invoice instance on admin, i can select the many to many fields 'activities', but i'd like to have an additional counter (eg. an IntegerField) as an Invoice field to count and save the quantity of each activity added to my Invoice instance. Is this possible?
thanks,
Luke

You could have a field on the model and override the save method
class Invoice(models.Model):
subject = models.ForeignKey(Subject)
date = models.DateField(default=date.today())
activities = models.ManyToManyField(Activity)
activity_count = models.PositiveIntegerField(default=0)
def save(self):
self.activity_count = self.activities.count()
super(Invoice, self).save()

Related

Listview must return only the courses that student have puchased in django

My models
User
class User(AbstractUser):
is_student = models.BooleanField(default=False)
....
purchased = models.ManyToManyField(Course, blank=True)
Course
class Course(models.Model):
title = models.CharField(max_length=1000)
.....
price = models.FloatField()
My Views
class StudentPurchasedcourse(ListView):
model = Course
template_name = 'tutspack/purchasedcourse.html'
context_object_name = 'course'
def get_queryset(self):
queruset = Course.objects.filter(pk=self.request.user.purchased.all()).order_by('title')
return queruset
My Urls.py
path('purchased_course/', views.StudentPurchasedcourse.as_view(), name='purchased-course'),
I want to return all the courses That student have purchased on the studentViewpage.
You should use reverse relation for such query. Start with adding related_name to purchased field of User:
class User(AbstractUser):
...
purchased = models.ManyToManyField(Course, blank=True, related_name="buyers")
Then you can easily use that name in making queries based on relations:
Course.objects.filter(buyers=self.request.user).order_by('title')
More about queries

django_filters, how do I query based on associated model?

My problem is like so,
I am using django-tables2 and I want to list some people on my page but these people should go through some queries. These queries will change according to information from other models.if the query is ok, this person will be in my table.
# My models
class AgeGroup(models.Model):
age_group = models.CharField(choices=age_choices, max_length=5)
class SolvedExam(models.Model):
age = models.ForeignKey(AgeGroup, on_delete=models.CASCADE, related_name='solved_exam_age_group')
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='solved_exam')
class Person(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='person')
age = models.ForeignKey(AgeGroup, on_delete=models.CASCADE, related_name='person_age_group')
*
*
*
class Exam(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='person')
age = models.ForeignKey(AgeGroup, on_delete=models.CASCADE, related_name='exam_age_group')
*
*
*
# my view
class PersonList(SingleTableMixin, FilterView):
table_class = PersonTable
model = Person
queryset = Person.objects.all()
paginate_by = 10
template_name = 'person/person-list.html'
filterset_class = PersonFilter
def get_queryset(self):
super(Ogrenciler, self).get_queryset()
return Person.objects.filter( **some query** )
raise Http404
I want to list the students if there are exams which is not finished in the person's age group. Thank you very much!
Where is the information about the examns, and the examns that where not passed? Typically I would expect an fields like Exman_id, class name, boolean passed etc.

Serialize Many to Many Relationship with Extra fields

Please I'm stuck trying to get around this issue. Guess there is something I'm not getting after looking at other similar questions.
I have these models:
class Dish(BaseModel):
class Meta:
verbose_name_plural = 'dishes'
name = models.CharField(_('dish'), max_length=100)
dish_type = models.CharField(_("dish type"), max_length=100)
price = models.PositiveIntegerField(_("price"))
def __str__(self):
return f"{self.name} costs {self.price}"
class Order(BaseModel):
dishes = models.ManyToManyField(Dish, through='DishOrder')
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
discount = models.PositiveIntegerField(_("total discount"), blank=True)
total = models.PositiveIntegerField(_("total"), blank=True)
shipping = models.PositiveIntegerField(_("shipping cost"), blank=True)
grand_total = models.PositiveIntegerField(_("grand total"), blank=True)
country = models.CharField(_('country code'), max_length=2)
def __str__(self):
return f"order from {self.customer} at {self.total}"
def get_absolute_url(self):
return reverse('order-details', kwargs={'pk': self.pk})
class DishOrder(models.Model):
dish = models.ForeignKey(Dish, on_delete=models.CASCADE, related_name='dishes')
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='dishes')
quantity = models.PositiveIntegerField(_("quantity"))
discount = models.PositiveIntegerField(_("discount"))
price = models.PositiveIntegerField(_('price'))
And the corresponding serializers like so:
class DishOrderSerializer(serializers.ModelSerializer):
class Meta:
model = DishOrder
fields = (
"quantity",
"discount",
"price"
)
class OrderSerializer(serializers.ModelSerializer):
dishes = DishOrderSerializer(source='dish', many=True)
class Meta:
model = Order
fields = (
"id",
"country",
"customer",
"dishes",
"total",
"discount",
"grand_total",
"voucher"
)
So as can be seen, I have a m2m relationship via a through table. However I can't get the serializer to work. This is the error I keep getting:
Got AttributeError when attempting to get a value for field dishes
on serializer OrderSerializer. The serializer field might be named
incorrectly and not match any attribute or key on the Order
instance. Original exception text was: 'Order' object has no attribute
'dish'.
I have been looking through this for some time trying to figure out what the error is. I will appreciate any help
Since you are using related_name='dishes' in model you should use dishes as source to the manytomany objects:
class OrderSerializer(serializers.ModelSerializer):
dishes = DishOrderSerializer(source='dishes', many=True)
or simple:
class OrderSerializer(serializers.ModelSerializer):
dishes = DishOrderSerializer(many=True)
Since source='dishes' redundant in case you named serializer's field dishes also.

How to use djando-table2 with class based view to display data from multiple table?

models.py
class DailyRecordManager(models.Manager):
def get_query_set(self):
qs = super(DailyRecordManager, self).get_query_set().order_by('date_organised')
return qs
class DailyRecord(models.Model):
date_organised = models.DateField('Ogransied Date', help_text=('Enter Date when the program is organised: CCYY-MM-DD'))
program_name = models.TextField('program name',)
venue = models.CharField('venue', max_length = 255, blank=True)
organiser = models.ForeignKey(Organiser, verbose_name = 'Organiser', related_name = 'organisers')
objects = models.Manager()
public = DailyRecordManager()
class Meta:
verbose_name = 'dailyrecord'
verbose_name_plural = 'dailyrecords'
ordering = ['-date_organised']
def __str__(self):
return self.program_name
class Participant(models.Model):
participant = models.CharField(max_length= 50, unique = True)
daily_record = models.ForeignKey(DailyRecord, verbose_name = 'program_name')
class Meta:
verbose_name = 'participant'
verbose_name_plural = 'participants'
def __str__(self):
return self.participant
views.py
class DailyActivityPageView(SingleTableView):
table_class = DailyRecordTable
queryset = DailyRecord.public.all()
# queryset = Participant(DailyRecord.public.all()) is not working
template_name = 'dailyrecord/daily-activity-record.html'
tables.py
class DailyRecordTable(tables.Table):
date_organised = tables.Column('Date')
program_name = tables.Column( 'Program Name')
venue = tables.Column( 'Venue')
organiser = tables.Column( 'Organiser')
participant = tables.Column( 'dailyrecord.participant')
# daily = tables.RelatedLinkColumn()
class Meta:
model = DailyRecord
Now what I need is to display the data from participant table too, corresponding to the daily_record foreign key.
Click this link to view the snapshot. see the last column of the table. I need the data of Participant.partcipant column here
Sorry for poor English.
Thank You
There are two problems here.
First is, that a daily record can have multiple participants. Thus, in order to fill last column you have to aggregate all possible participants into that column (for example as list).
Second is, that you should make Participant backwards related to DailyRecord by adding attribute "related_name" to daily_record in your Participant model, like this:
daily_record = models.ForeignKey(DailyRecord, verbose_name = 'program_name', related_name="participants")
Now, you should simply get participants from daily_record like this:
participants = DailyRecord.public.first().participants.all()
If you had OneToOneField instead of ForeignKey you could add (single) participant to table like this:
participant = tables.Column( "Participant", accessor='participant')

django handle multiple forms

My model:
class HospitalDoctor(models.Model):
hospital = models.ForeignKey(Hospital)
full_name = models.CharField(max_length=100, unique=True)
expertization = models.CharField(max_length=50)
nmc_no = models.CharField(max_length=20)
timings = models.ManyToManyField('Timing', related_name='shift_timing')
appointment = models.IntegerField(default=0)
def __unicode__(self):
return self.full_name
class Timing(models.Model):
hospital = models.ForeignKey(Hospital)
doctor = models.ForeignKey(HospitalDoctor)
day = models.CharField(max_length=20)
mng_start = models.IntegerField()
mng_end = models.IntegerField()
eve_start = models.IntegerField()
eve_end = models.IntegerField()
def __unicode__(self):
return self.day
and I have created form for this:
class HospitalDoctorInfoForm(forms.ModelForm):
class Meta:
model = HospitalDoctor
fields = ('hospital','full_name', 'expertization', 'nmc_no')
class TimingForm(forms.ModelForm)
class Meta:
model = Timing
fields = ('day','mng_start', 'mng_end', 'eve_start', 'eve_end')
I want to save the two form at once. The TimingForm contains the schedule of a doctor for 1 week so I need 7 forms for 7 days and the day should be set as per week initially like Sunday, Monday....DoctorInfoForm contains the information about doctor.
I tried using CreateView but I need to use form_class there?
How can I make it possible? Any suggestion.
It is just simple in django.
if HospitalDoctorinfoform.is_valid() and Timingform.is_valid():
#Dosomething
HospitalDocinfoform.save()
Timingform.save()
BIngo!!