How to access MTM field with through setting to template - django

price = models.ManyToManyField("price.Price", verbose_name='Ціни', through='services_count', through_fields=('service','price'), blank=True)
and through model
class services_count(models.Model):
quantity = models.IntegerField(verbose_name='Кількість цієї послуги у сервісі', null=True)
service = models.ForeignKey("medservices.Medservices", verbose_name='Послуга або акція', on_delete=models.CASCADE,default=None)
price = models.ForeignKey("price.Price", verbose_name='Ціна яка', on_delete=models.CASCADE, default=None)
views.py
def service_page(request, post_slug):
post_content = Medservices.price.through.objects.all()
post = get_object_or_404(Medservices, slug=post_slug)
post_dict = {'post_rows':post , 'post_alt':post_content,}
return render(request, 'medservices/service.html', context=post_dict)
So i want to have oportunity to access service_count model through model with MTM field

Related

Cannot assign "'user_name'": "Class.user" must be a "Account_class" instance

enter image descripI am getting this error when I try to make a post requesttion here
How to can I solve this problem?
Here is my model:
class Coffee(models.Model):
name = models.CharField(max_length=60)
ratings = models.CharField(max_length=5)
taste = models.TextField()
coffeeType = models.CharField(max_length=60)
price = models.CharField(max_length=60)
img = models.CharField(max_length=200)
updated_at = models.DateTimeField(auto_now_add=True)
shopName = models.CharField(max_length=60)
coffeeShopID = models.CharField(max_length=200)
location = models.CharField(max_length=200)
user = models.ForeignKey(Account, on_delete=models.CASCADE, null=False, blank=False, related_name='user')
def __str__(self):
return self.name[0:50]
class Meta:
ordering = ['-updated_at']
Here is the serializer of that model:
class CoffeeSerializers(serializers.ModelSerializer):
class Meta:
model = Coffee
fields = '__all__'
Here is views for post request:
def addCoffee(request):
data = request.data
coffee = Coffee.objects.create(
name=data['name'],
ratings=data['ratings'],
taste=data['taste'],
coffeeType=data['coffeeType'],
price=data['price'],
img=data['img'],
shopName=data['shopName'],
coffeeShopID=data['coffeeShopID'],
location=data['location'],
user=data['user']
)
coffee.save()
serializer = CoffeeSerializers(coffee)
return Response(serializer.data)
i can only assume how your Account model looks like, problem is that you must send Account model, but you are sending string data['user']
def addCoffee(request):
data = request.data
account_object = Account.objects.get(THIS_IS_ACCOUNT_NAME = data['user'])
coffee = Coffee.objects.create(
name=data['name'],
ratings=data['ratings'],
taste=data['taste'],
coffeeType=data['coffeeType'],
price=data['price'],
img=data['img'],
shopName=data['shopName'],
coffeeShopID=data['coffeeShopID'],
location=data['location'],
user=account_object
)
coffee.save()
serializer = CoffeeSerializers(coffee)
return Response(serializer.data)

price() missing 1 required positional argument: 'self' while trying to calculate the price in Django Rest Framework

I am trying to create a case where when I call the order create api, the price will be calculated itself and saved in the database but I am getting this error in the postman.
Error: price() missing 1 required positional argument: 'self
My models:
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
ordered_date = models.DateTimeField(auto_now_add=True)
ordered = models.BooleanField(default=False)
total_price = models.CharField(max_length=50,blank=True,null=True)
#billing_details = models.OneToOneField('BillingDetails',on_delete=models.CASCADE,null=True,blank=True,related_name="order")
def __str__(self):
return self.user.email
def price(self):
total_item_price = self.quantity * self.item.varaints.price
return total_item_price
class OrderItem(models.Model):
#user = models.ForeignKey(User,on_delete=models.CASCADE, blank=True
#orderItem_ID = models.UUIDField(max_length=12, editable=False,default=str(uuid.uuid4()))
orderItem_ID = models.CharField(max_length=12, editable=False, default=id_generator)
order = models.ForeignKey(Order,on_delete=models.CASCADE, blank=True,null=True,related_name='order_items')
item = models.ForeignKey(Product, on_delete=models.CASCADE,blank=True, null=True)
order_variants = models.ForeignKey(Variants, on_delete=models.CASCADE,blank=True,null=True)
quantity = models.IntegerField(default=1)
total_item_price = models.PositiveIntegerField(blank=True,null=True,default=price())
ORDER_STATUS = (
('To_Ship', 'To Ship',),
('Shipped', 'Shipped',),
('Delivered', 'Delivered',),
('Cancelled', 'Cancelled',),
)
order_item_status = models.CharField(max_length=50,choices=ORDER_STATUS,default='To_Ship')
Here quantity field is present in the OrderItem model itself but the price is present in the Variant model which is related to the Product model like this.
Things I tried:
I tried removing brackets () in price, but got same error.
If I tried putting price function inside class model before total_itel_price field, it says self is required inside bracket of price, and if I put self, = is required and I dont know to put in price(self=??)
Other Models:
Class Variants(models.Model):
...#other fields
price = models.DecimalField(decimal_places=2, max_digits=20,default=500)
Class Product(models.Model):
...#other fields
variants = models.ManyToManyField(Variants,related_name='products')
My serializer:
class OrderSerializer(serializers.ModelSerializer):
billing_details = BillingDetailsSerializer()
order_items = OrderItemSerializer(many=True)
user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
class Meta:
model = Order
fields = ['id','user','ordered_date','order_status', 'ordered', 'order_items', 'total_price','billing_details']
# depth = 1
def create(self, validated_data):
user = self.context['request'].user
if not user.is_seller:
order_items = validated_data.pop('order_items')
billing_details = validated_data.pop('billing_details')
order = Order.objects.create(user=user,**validated_data)
BillingDetails.objects.create(user=user,order=order,**billing_details)
for order_items in order_items:
OrderItem.objects.create(order=order,**order_items)
else:
raise serializers.ValidationError("This is not a customer account.Please login as customer.")
Updated Code:
class OrderItem(models.Model):
#total_item_price = models.PositiveIntegerField(blank=True,null=True,default=0) #commented out this field other fields are same as above
order_item_status = models.CharField(max_length=50,choices=ORDER_STATUS,default='To_Ship')
#property
def price(self):
return self.quantity * self.item.varaints.price
class OrderItemSerializer(serializers.ModelSerializer):
order = serializers.PrimaryKeyRelatedField(read_only=True)
price = serializers.ReadOnlyField()
class Meta:
model = OrderItem
fields = ['id','order','orderItem_ID','item','order_variants', 'quantity','order_item_status','price']
# depth = 1
Order Serializer is just like above. It includes OrderItemSerializer as shown:
class OrderSerializer(serializers.ModelSerializer):
billing_details = BillingDetailsSerializer()
order_items = OrderItemSerializer(many=True)
user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
class Meta:
model = Order
fields = ['id','user','ordered_date','order_status', 'ordered', 'order_items', 'total_price','billing_details']
Update for Order total_price calculation.
This is what I did for total_price calculation but I am not getting total_price field in the api response, there is no error though.
class Order(models.Model):
.....#same fields as above
#property
def total_order_price(self):
return sum([_.price for _ in self.order_items_set.all()])
I have used price function in the OrderItem model and my instance of OrderItem is order_items. What is the issue??
Try this
class Order(models.Model):
"""Stores the details of the order"""
user: User = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
ordered_date = models.DateTimeField(auto_now_add=True)
ordered = models.BooleanField(default=False)
# billing_details = models.OneToOneField('BillingDetails',on_delete=models.CASCADE,null=True,blank=True,related_name="order")
def __str__(self) -> str:
return self.user.email
#property
def total_price(self) -> int:
"""
Dropped the total price field and created it as property
This is not the best practice, I am leaving that as practice for you :)
"""
return sum([_.total_item_price for _ in self.orderitem_set.all()])
class OrderItem(models.Model):
"""Order Item stores the details of the each order item"""
orderItem_ID: str = models.CharField(
max_length=12, editable=False, default=id_generator
)
order: Order = models.ForeignKey(
Order,
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="order_items",
)
item: Product = models.ForeignKey(
Product, on_delete=models.CASCADE, blank=True, null=True
)
order_variants: Variants = models.ForeignKey(
Variants, on_delete=models.CASCADE, blank=True, null=True
)
quantity: int = models.IntegerField(default=1)
price = models.PositiveIntegerField()
#property
def total_item_price(self):
"""
Calculates total item price for the item
Here you can also add additional logics such as
taxes per item etc
"""
return self.price * self.quantity
ORDER_STATUS = (
("To_Ship", "To Ship"),
("Shipped", "Shipped"),
("Delivered", "Delivered"),
("Cancelled", "Cancelled"),
)
order_item_status = models.CharField(
max_length=50, choices=ORDER_STATUS, default="To_Ship"
)
This code finally worked for OrderItem price calculation:
class OrderItem(models.Model):
.....#fields same as above
#total_item_price = models.PositiveIntegerField(blank=True,null=True,default=0)
ORDER_STATUS = (
('To_Ship', 'To Ship',),
('Shipped', 'Shipped',),
('Delivered', 'Delivered',),
('Cancelled', 'Cancelled',),
)
order_item_status = models.CharField(max_length=50,choices=ORDER_STATUS,default='To_Ship')
#property
def price(self):
total_item_price = self.quantity * self.order_variants.price
return total_item_price
There was a typo in variants. Also, I should be using order_variants instead of item.variants because item has many variants but the user selects only one which has a unique price.

django - How can I prefill formset forms data using database query result?

I am creating a student attendance form where need to get details of student name, student class and Id from student model based on teacher selecting student class in one form. I have tried using initial by using for loop on query data to prefill the form in formset, however it populates data for one record only. Below is the code for forms.py, models and views.py. Can someone help on this
forms.py
class student(models.Model):
studentid = models.AutoField(primary_key=True)
Gender = models.CharField(max_length=6, choices=gender, null=True)
Name = models.CharField(max_length=100, null=True)
DOB = models.DateField(null=True)
Image = models.ImageField(null=True, upload_to='images')
Status = models.CharField(max_length=10, choices=statchoice, null=True)
Father_name = models.CharField(max_length=100, null=True)
Mother_name = models.CharField(max_length=100, null=True)
Address = models.CharField(max_length=200, null=True)
Contact_no = models.IntegerField(null=True)
Email = models.EmailField(null=True)
Admission_class = models.CharField(max_length=40, null=True, choices=grade)
Admission_date = models.DateField(null=True)
Current_class = models.CharField(max_length=40, null=True, choices=grade)
Leaving_date = models.DateField(null=True, blank=True)
objects = models.Manager()
def __str__(self):
return str(self.studentid)
class student_attendance(models.Model):
Student_ID = models.CharField(max_length=100, null=True)
Student_Name = models.CharField(max_length=100, null=True)
Student_class = models.CharField(max_length=100, null=True, choices=grade)
Attendance_date = models.DateField(null=True, auto_now_add=True, blank=True)
Attendance_status = models.CharField(choices=attendance, null=True, max_length=10)
objects = models.Manager()
Views.py
def student_attend(request):
if request.method == 'POST':
data = request.POST.get('studentGrade')
formset_data = student.objects.filter(Current_class=data)
AttendanceFormSet = formset_factory(std_attendance, extra=(len(formset_data))-1)
for element in formset_data:
formset = AttendanceFormSet(initial=[
{'Student_ID': element.studentid, 'Student_Name':element.Name, 'Student_class':element.Current_class, 'Attendance_status':"Present"}
])
param = {'formset':formset}
return render(request, 'home/student_attendance.html', param)
return render(request, 'home/student_attendance.html')
form.py:
class student_register(ModelForm):
class Meta:
model = student
fields = '__all__'
class std_attendance(ModelForm):
class Meta:
model = student_attendance
fields = '__all__'
Each iteration in your loop you override the formset, that is why only a single form is filled, you need to fill the param with all the forms inside the loop this way:
initial = []
for element in formset_data:
initial.append({'Student_ID': element.studentid, 'Student_Name':element.Name, 'Student_class':element.Current_class, 'Attendance_status':"Present"}
formset = AttendanceFormSet(initial=initial)

How can I toggle a form having prefilled content with an edit button in django

I have a form that users can fill to leave a review. On the same page, the reviews are displayed with a button to edit the review. When the edit button is clicked, I would like for the form to be pre-filled with the appropriate review data, so that it can be edited and updated in the database.
models
class Clinic(models.Model):
practitioner = models.OneToOneField(User, on_delete=models.CASCADE)
lat = models.FloatField(null=True, blank=True)
lng = models.FloatField(null=True, blank=True)
web = models.CharField(null=True, blank=True, max_length=128)
name = models.CharField(max_length=128, )
phone = PhoneNumberField()
description = models.TextField(max_length=5000)
street = models.CharField(max_length=128, )
city = models.CharField(max_length=128, )
def __str__(self):
return self.name
def save(self):
super().save()
class Reviews(models.Model):
title = models.CharField(max_length=128)
body = models.TextField(max_length=500)
author = models.ForeignKey(User, on_delete=models.CASCADE)
clinic = models.ForeignKey(Clinic,
null=True,
blank=True,
on_delete=models.CASCADE)
Form
class ReviewForm(forms.ModelForm):
class Meta:
model = Reviews
fields = (
'title',
'body',
)
View
def clinic_profile(request, clinic_id):
clinic = Clinic.objects.filter(pk=clinic_id)
form = ReviewForm(request.POST)
if request.method == 'POST':
if form.is_valid():
r_clinic = Clinic.objects.get(pk=clinic_id)
title = form.cleaned_data.get("title")
body = form.cleaned_data.get("body")
review = Reviews(title=title,
body=body,
author=request.user,
clinic=r_clinic)
review.save()
messages.success(request, f'Thank you for leaving a review!')
clinic_reviews = Reviews.objects.filter(clinic=clinic_id)
latlng = {
"lat": clinic[0].lat,
"lng": clinic[0].lng,
"name": clinic[0].name
}
def get_mods():
profile = Profile.objects.filter(user=Clinic.objects.get(
pk=clinic_id).practitioner)
mods = profile[0].mods.all().values('name') if profile else []
mods = [(q['name']) for q in mods]
return mods
return render(
request, 'clinic_profile.html', {
'clinic': clinic,
'mods': get_mods,
'latlng': latlng,
'api_key': api_key,
'reviews': clinic_reviews,
'form': form,
})
Screenshot

Forms in Django. How to initialize model field from form?

In models.py:
class Client(AbstractBaseUser):
username = models.CharField(max_length=32, unique=True)
email = models.EmailField('email address', unique=True, db_index=True)
avatar = models.ImageField('avatar', upload_to='avatars')
id = id(object)
class Order(models.Model):
class Meta():
db_table = 'order'
short_desc = models.CharField(max_length=30)
subject = models.ForeignKey(Subject, blank=True)
user_id = models.ForeignKey('Client', to_field='id', related_name='client_id', default='0', blank=True)
performer_id = models.ForeignKey('Client', to_field='id', related_name='performer_id', default='0', blank=True)
worktype = models.ForeignKey(Type, blank=True)
level = models.IntegerField(default=0, blank=True)
readiness = models.BooleanField(default=False, blank=True)
description = models.TextField(max_length=2000, blank=True)
file = models.FileField(upload_to='orderfiles', blank=True)
#maxdate = models.DateField(blank=True)
addate = models.DateField(auto_now=True, blank=True)
price = models.IntegerField(max_length=10, blank=True)
responses = models.IntegerField(blank=True)
In forms.py:
class AddOrderForm(forms.ModelForm):
short_desc = forms.CharField(widget=forms.TextInput,label="Краткое описание(послужит именем)")
subject = forms.ModelChoiceField(queryset=Subject.objects.all(), label="Предмет")
worktype = forms.ModelChoiceField(queryset=Type.objects.all(), label="Тип")
level = forms.IntegerField(widget=forms.TextInput,label="Уровень сложности (от 1 до 5)")
description = forms.CharField(widget=forms.TextInput,label="Полное описание")
#maxdate = forms.DateField(widget=forms.TextInput,label="maxdate")
price = forms.IntegerField(widget=forms.TextInput,label="Ваша цена")
responses = forms.IntegerField(widget=forms.TextInput,label="Кол-во ответов на заказ")
class Meta:
model = Order
fields = ['short_desc', 'level', 'description', 'price', 'responses', 'subject', 'worktype']
In views.py:
def addorder(request, user_id):
"""
Adding Order view
"""
if request.POST:
form = AddOrderForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
return redirect('/')
auth1 = auth.get_user(request).username
return render_to_response('customer.html', { 'form': form,'username' : auth1}, context_instance=RequestContext(request))
I need the field user_id in class Order to be initialized immediately after adding order(). Where should I do it and in which way? I need something like this logic: Client adds an Order through AddOrderForm and then user_id field of just added object of class Order has to be initialized with an object of class Client, whose id equals user_id in parameters of addorder() function.
You can do that using commit=False while saving the form. This is typical way of saving the object using model form which has fewer fields.
def addorder(request, user_id):
"""
Adding Order view
"""
if request.POST:
form = AddOrderForm(request.POST)
if form.is_valid():
order = form.save(commit=false)
order.client_id = Client.objects.get(id=user_id)
order.save()
return redirect('/')
else:
return redirect('/')
auth1 = auth.get_user(request).username
return render_to_response('customer.html',
{ 'form': form,'username' : auth1},
context_instance=RequestContext(request))
Disclaimer: Handle errors e.g. Client.objects.get() may fail. Use appropriate fields to search.