I want to get the 'profilephoto' from the Profile model for each Review that a Product has but that requires the Review models profile_id which is already apart of a context. Is there any way to do this?
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
profilephoto = models.ImageField(default='profiles/default_profile.jpg', upload_to='profiles')
class Product(models.Model):
name = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
category = models.CharField(max_length=100)
releasedate = models.DateField()
description = models.TextField()
productphoto = models.ImageField(default='products/default_product.jpg', upload_to='products')
class Review(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.PositiveSmallIntegerField(default=1, validators = [MinValueValidator(1), MaxValueValidator(5)])
reviewtext = models.TextField()
views.py
class ProductDetailView(TemplateView):
# template_name = 'reviewApp/test.html'
template_name = 'reviewApp/product_detail.html'
def get_context_data(self, **kwargs):
prod = self.kwargs['pk']
context = super(ProductDetailView, self).get_context_data(**kwargs)
context['Products'] = Product.objects.filter(id=prod)
context['Reviews'] = Review.objects.filter(product=prod)
prof = Review.objects.only('profile_id')
context['Profiles'] = Profile.objects.filter(id__in=prof)
return context
class ProductDetailView(TemplateView):
# template_name = 'reviewApp/test.html'
template_name = 'reviewApp/product_detail.html'
def get_context_data(self, **kwargs):
prod = self.kwargs['pk']
context = super(ProductDetailView, self).get_context_data(**kwargs)
context['Product'] = Product.objects.get(id=prod)
context['Reviews'] = Review.objects.filter(product_id=prod)
profile_ids = Review.objects.values_list('profile_id', flat=True)
context['Profiles'] = Profile.objects.filter(id__in=profile_ids)
return context
Related
I am creating application to manage home budget. I've got a few models - Date, Expense, Category, Income.
It looks like this
class Date(models.Model):
name = models.CharField(max_length = 15)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='date')
class Category(models.Model):
name = models.CharField(max_length=100)
budget = models.DecimalField(max_digits=8, decimal_places=2)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='category')
date = models.ForeignKey(Date, on_delete=models.CASCADE, related_name='date', default='Styczeń 2022')
class Expense(models.Model):
name = models.CharField(max_length=100)
amount = models.DecimalField(max_digits=8, decimal_places=2)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
account = models.ForeignKey(Account, on_delete=models.CASCADE, related_name="account")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='expense')
date = models.ForeignKey(Date, on_delete=models.CASCADE, default='Styczeń 2022')
class Income(models.Model):
name = models.CharField(max_length=100)
amount = models.DecimalField(max_digits=8, decimal_places=2)
account = models.ForeignKey(Account, on_delete=models.CASCADE, related_name="account_income")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='income')
First of all user should choose a "Date", next it goes to DateDetailView. And on this DetailView I want to display Expense only for this Date. I tried with objects.filter, but I don't know how I should write it properly.
I wrote something like this
class DateDetailView(DetailView):
model = Date
template_name = 'expense/date_detail.html'
context_object_name = 'date'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['expense'] = Expense.objects.filter(date=F('pk'))
return context
I also tried this
class DateDetailView(DetailView):
model = Date
template_name = 'expense/date_detail.html'
context_object_name = 'date'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['expense'] = Expense.objects.filter(date=self.date)
return context
Have you got any ideas? Thanks!
Okey, I found a solution.
class DateDetailView(DetailView):
model = Date
template_name = 'expense/date_detail.html'
context_object_name = 'date'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['expense'] = Expense.objects.filter(date=self.object)
return context
i'm building a small webstore , in the product page i put the order form using FormMixin and TemplateView, when i submit the order i get a "Direct assignment to the forward side of a many-to-many set is prohibited. Use product.set() instead." error
Bellow you can check the code
Models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255, unique=True, )
description = models.TextField(max_length=1500)
class Meta:
verbose_name_plural = "categories"
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
nominal_price = models.PositiveIntegerField(verbose_name='prix normal',)
reduced_price = models.PositiveIntegerField(blank=True, null=True)
quantity = models.PositiveIntegerField(default=10)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
photo = models.ImageField(upload_to="img/products/", default="img/products/user_default.png")
def __str__(self):
return self.name
class Customer(models.Model):
full_name = models.CharField(max_length=150)
address = models.CharField(max_length=1500, null=True)
phone = models.IntegerField()
city = models.CharField(max_length=100)
email = models.EmailField(null=True)
class Order (models.Model):
product = models.ManyToManyField(Product, through='OrderProduct')
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
class OrderProduct(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
Views.py
class ProductDetailView(FormMixin, TemplateView):
model = Product
template_name = 'product.html'
form_class = OrderForm
def get_success_url(self):
return reverse('index')
def post(self, request, *args, **kwargs):
context = self.get_context_data()
form = OrderForm(request.POST)
if context['form'].is_valid():
product = get_object_or_404(Product, name=self.kwargs['product_name'])
customer = form.save()
Order.objects.create(product=product, customer=customer)
return super(TemplateView, self)
def get_context_data(self, **kwargs):
context = super(ProductDetailView, self).get_context_data(**kwargs)
context['product'] = Product.objects.get(name=self.kwargs['product_name'])
context['form'] = self.get_form()
return context
urls.py
path('', views.ProductListView.as_view(), name='index'),
Did i missed something
For handling many-to-many relations, you cannot directly set the product from Order. Also you would need to create the order first before you can set or add a product:
order = Order.objects.create(customer=customer)
order.product.add(product)
I am a student studying Django. Currently, the member information has been entered in the Member table. I want to create Mypage so that member information registered in the Member table can be modified, and develop so that member information can be modified on Mypage. But while developing, I faced the following error: How can I solve this? Any help would be greatly appreciated.
Detail Error :
AttributeError at /mypage/mypage_modify/
'QuerySet' object has no attribute 'save'
Request Method: POST
Request URL: http://127.0.0.1:8000/mypage/mypage_modify/
Django Version: 3.1.5
Exception Type: AttributeError
Exception Value:
'QuerySet' object has no attribute 'save'
Exception Location: C:\zeronine_project\mypage\views.py, line 27, in mypage_modify
Python Executable: D:\anaconda3\envs\vnv_zn\python.exe
Python Version: 3.7.6
Python Path:
['C:\\zeronine_project',
'D:\\anaconda3\\envs\\vnv_zn\\python37.zip',
'D:\\anaconda3\\envs\\vnv_zn\\DLLs',
'D:\\anaconda3\\envs\\vnv_zn\\lib',
'D:\\anaconda3\\envs\\vnv_zn',
'D:\\anaconda3\\envs\\vnv_zn\\lib\\site-packages']
Server time: Thu, 08 Jul 2021 21:05:53 +0900
view.py
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect
from mypage.forms import *
from zeronine.models import *
# Create your views here.
def mypage_list(request):
categories = Category.objects.all()
return render(request, 'mypage/mypage_list.html', {'categories':categories})
def mypage_modify(request):
current_category = None
categories = Category.objects.all()
member = Member.objects.all()
if not request.user.is_authenticated:
return HttpResponseRedirect(reverse('zeronine:login'))
if request.method == "POST":
member.name = request.POST['name']
member.password = request.POST['password']
member.username = request.user
member.save()
return redirect('zeronine:post')
else:
memberForm = MemberForm
return render(request, 'mypage/mypage_modify.html', {'memberForm':memberForm, 'member':member, 'current_category': current_category, 'categories': categories})
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.urls import reverse
# 회원
class Member(AbstractUser):
username = models.CharField(primary_key=True, max_length=20, verbose_name='아이디')
name = models.CharField(max_length=20, verbose_name='이름', default='')
password = models.CharField(max_length=64, verbose_name='비밀번호')
phone = models.CharField(max_length=64, verbose_name='전화번호')
def __str__(self):
return self.username
class Meta:
verbose_name = ('Member')
verbose_name_plural = ('Members')
# 카테고리
class Category(models.Model):
category_code = models.AutoField(primary_key=True)
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, allow_unicode=True)
class Meta:
ordering =['category_code']
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('zeronine:product_in_category', args=[self.slug])
# 상품
class Product(models.Model):
product_code = models.AutoField(primary_key=True)
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
category_code = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='products')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=False, allow_unicode=True)
image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
benefit = models.TextField()
detail = models.TextField()
target_price = models.IntegerField()
start_date = models.DateField()
due_date = models.DateField()
class Meta:
ordering = ['product_code']
index_together = [['product_code', 'slug']]
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('zeronine:product_detail', args=[self.product_code, self.slug])
class Post(models.Model):
post_code = models.AutoField(primary_key=True)
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
title = models.CharField(max_length=64)
content = models.TextField()
register_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Meta:
ordering = ['register_date']
# 댓글(댓글코드, 게시글코드(fk), 아이디(fk), 내용, 등록날짜)
class Comment(models.Model):
comment_code = models.AutoField(primary_key=True)
post_code = models.ForeignKey(Post, on_delete=models.CASCADE, db_column='post_code')
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
content = models.TextField()
register_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.content
class Meta:
ordering = ['register_date']
# Zzim 모델부터 새로 추가하려는 모델들 입니다.
# 찜하기(찜코드, 아이디(fk), 상품코드(fk))
class Zzim(models.Model):
zzim_code = models.AutoField(primary_key=True)
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
def __str__(self):
return str(self.zzim_code)
# 상품이미지(이미지코드, 상품코드(fk), 이미지경로)
class Photo(models.Model):
photo_code = models.AutoField(primary_key=True)
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
photo = models.ImageField(upload_to="photos/%Y%m%d")
def __str__(self):
return str(self.photo_code)
class Meta:
ordering = ['photo_code']
# 옵션(옵션코드, 옵션명, 상품코드(fk))
class Option(models.Model):
option_code = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
def __str__(self):
return self.name
# 옵션값(옵션값코드, 옵션값명, 옵션코드(fk), 상품코드(fk))
class Value(models.Model):
value_code = models.AutoField(primary_key=True)
option_code = models.ForeignKey(Option, on_delete=models.CASCADE, db_column='option_code')
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
name = models.CharField(max_length=32)
def __str__(self):
return self.name
# 옵션지정상품(옵션지정상품코드, 상품코드(fk), 가격, 참여수량)
class Designated(models.Model):
designated_code = models.AutoField(primary_key=True)
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
price = models.IntegerField()
rep_price = models.BooleanField(default=True)
class Meta:
ordering = ['designated_code']
def __str__(self):
return str(self.designated_code)
# 상품옵션구성(상품옵션구성코드, 옵션지정상품코드, 옵션값코드)
class Element(models.Model):
element_code = models.AutoField(primary_key=True)
designated_code = models.ForeignKey(Designated, on_delete=models.CASCADE, db_column='designated_code')
value_code = models.ForeignKey(Value, on_delete=models.CASCADE, db_column='value_code')
class Meta:
ordering = ['element_code']
def __str__(self):
return str(self.element_code)
# 참여(참여코드, 아이디(fk), 상품코드(fk), 수량)
class Join(models.Model):
join_code = models.AutoField(primary_key=True)
username = models.ForeignKey(Member, on_delete=models.CASCADE, db_column='username')
product_code = models.ForeignKey(Product, on_delete=models.CASCADE, db_column='product_code')
part_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.join_code)
class Meta:
ordering = ['join_code']
#참여상세(참여상세코드, 수량, 가격, 참여코드, 옵션지정상품코드)
class JoinDetail(models.Model):
joindetail_code = models.AutoField(primary_key=True)
join_code = models.ForeignKey(Join, on_delete=models.CASCADE, db_column='join_code')
designated_code = models.ForeignKey(Designated, on_delete=models.CASCADE, null=True, blank=True, db_column='designated_code')
quantity = models.IntegerField()
price = models.IntegerField()
def __str__(self):
return str(self.joindetail_code)
class Meta:
ordering = ['joindetail_code']
You are not specifying a member object to update. member = Member.objects.all() will get a queryset of all the member objects in your database.
Try doing:
def mypage_modify(request):
current_category = None
categories = Category.objects.all()
member = Member.objects.all()
if not request.user.is_authenticated:
return HttpResponseRedirect(reverse('zeronine:login'))
if request.method == "POST":
member = Member.objects.get(name=request.POST['name']) #specifying the member
member.name = request.POST['name']
member.password = request.POST['password']
member.username = request.user
member.save()
return redirect('zeronine:post')
else:
memberForm = MemberForm
return render(request, 'mypage/mypage_modify.html', {'memberForm':memberForm, 'member':member, 'current_category': current_category, 'categories': categories})
Or if you are making a new member object then instead of member = Member.objects.get(name=request.POST['name'])
Do: member = Member()
EDIT:
Not sure why you'd want to do this in practise, but to change every member object in the database you'd do the following:
def mypage_modify(request):
current_category = None
categories = Category.objects.all()
member = Member.objects.all()
if not request.user.is_authenticated:
return HttpResponseRedirect(reverse('zeronine:login'))
if request.method == "POST":
for m in member:
m.name = request.POST['name']
m.password = request.POST['password']
m.username = request.user
m.save()
return redirect('zeronine:post')
What you're accessing with member = Member.objects.all() is a list of Member objects.
To get a desired member use
member = Member.objects.get()
or
member = Member.objects.filter()
In the latter, you'd also need to check
if member:
member = member.first()
Check
https://docs.djangoproject.com/en/3.2/ref/models/querysets/#filter
https://docs.djangoproject.com/en/3.2/ref/models/querysets/#get
I have a custom user model from AbstractBaseUser and BaseUserManager. The user model is extended to a model called Employee. The employee model is related with(Foreignkey) two other model named WorkExperience and education. A single template form is designed with Employee, WorkExperience and Education modelform.
models.py:
class Employee(models.Model):
"""
Create employee attributes
"""
employee_user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
e_id = models.IntegerField(unique=True, null=True)
first_name = models.CharField(max_length=128, null=True)
last_name = models.CharField(max_length=128, null=True)
gender_choices = (
('Male', 'Male'),
('Female', 'Female'),
)
......
#receiver(post_save, sender=UserProfile)
def create_or_update_user_profile(sender, instance, created, **kwargs):
if created:
Employee.objects.create(employee_user=instance, email=instance.email)
instance.employee.save()
class WorkExperience(models.Model):
"""
Stores employee previous work experiences
"""
employee_user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
employee = models.ForeignKey('Employee', related_name='we_employee', on_delete=models.CASCADE, null=True)
previous_company_name = models.CharField(max_length=128, null=True)
job_designation = models.CharField(max_length=128, null=True)
from_date = models.DateField(null=True)
to_date = models.DateField(null=True)
job_description = models.CharField(max_length=256, null=True)
class Education(models.Model):
"""
Stores employee education background
"""
employee_user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)
employee = models.ForeignKey('Employee', related_name='edu_employee', on_delete=models.CASCADE, null=True)
institution_name = models.CharField(max_length=128, null=True)
degree = models.CharField(max_length=128, null=True)
passing_year = models.IntegerField(null=True)
result = models.DecimalField(max_digits=5, decimal_places=2, null=True)
I have a CreateView of this three models. I have three modelform. I implemented CRUD using this modelforms. My problem is in UpdateView. When I call UpdateView an error is showing stating WorkExperience matching query does not exist.I think the query is not correct.
views.py:
class EmployeeUpdateView(LoginRequiredMixin, UpdateView):
"""
Update a created a employee
"""
login_url = '/authentication/login/'
template_name = 'employee/employee_update_form.html'
form_class = EmployeeAddModelForm
work_form_class = WorkExperienceForm
education_form_class = EducationForm
context_object_name = 'employee'
model = Employee
queryset = Employee.objects.all()
# Override default get method
def get(self, request, *args, **kwargs):
id_ = self.kwargs.get("id")
employee_id = Employee.objects.get(id=id_)
work_info = WorkExperience.objects.get(employee=employee_id)
education_info = Education.objects.get(employee=employee_id)
form = self.form_class(instance=employee_id)
work_form = self.work_form_class(prefix='work_form', instance=work_info)
education_form = self.education_form_class(prefix='education_form',instance=education_info)
return render(request, self.template_name, {
'form': form,
'work_form': work_form,
'education_form': education_form,
'supervisor_assigned': employee_id.supervisor_select
}
)
# Override default post method
def post(self, request, *args, **kwargs):
id_ = self.kwargs.get("id")
employee_id = Employee.objects.get(id=id_)
work_info = WorkExperience.objects.get(employee=employee_id)
education_info = Education.objects.get(employee=employee_id)
form = self.form_class(request.POST, instance=employee_id)
work_form = self.work_form_class(request.POST, prefix='work_form', instance=work_info)
education_form = self.education_form_class(request.POST, prefix='education_form',instance=education_info)
# Check form validation
if form.is_valid() and work_form.is_valid() and education_form.is_valid():
instance = form.save()
work = work_form.save(commit=False)
education = education_form.save(commit=False)
work.employee = instance
education.employee = instance
work.save()
education.save()
return redirect('employee:employee-list')
return render(request, self.template_name, {
'form': form,
'work_form': work_form,
'education_form': education_form
}
)
urls.py:
urlpatterns = [
path('employee-list/', EmployeeListView.as_view(), name='employee-list'),
path('employee-add/', EmployeeAddView.as_view(), name='employee-add'),
path('employee-list/<int:id>/', EmployeeDetailView.as_view(), name='employee-detail'),
path('employee-list/<int:id>/update/', EmployeeUpdateView.as_view(), name='employee-update'),
How can I modify my query? i think my query is not correct.
you need to use foreign Key to use the employee id :
work_info = WorkExperience.objects.get(employee__id=employee_id)
I Hope it works fine
I have 4 categories on my site. How can I write one class PageViews(ListView) for four same pages with different posts. And same question, how to write class DeteilViews(DetailView) for each posts? My models below.
class Category(models.Model):
category = models.CharField(max_length=50)
slug = models.CharField(max_length=60, unique=True)
class Topic(models.Model):
topic = models.CharField(max_length=50)
slug = models.CharField(max_length=60, unique=True)
category = models.ManyToManyField(Category)
class Page(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
datetime = models.DateTimeField()
title = models.CharField(max_length=60)
slug = models.CharField(max_length=250, unique=True)
short_text = models.CharField(max_length=255)
text = models.TextField()
image = models.ImageField(upload_to='media/news_img')
img_source = models.CharField(max_length=255)
page_source = models.CharField(max_length=60)
parsing_date = models.DateTimeField(auto_now=True)
objects = models.Manager()
def get_absolute_url(self):
return reverse('news:detail', args=[self.category.slug, self.topic.slug, self.slug])
class Comment(models.Model):
page = models.ForeignKey(Page, on_delete=models.CASCADE)
comment = models.TextField()
author = models.CharField(max_length=55)
datetime = models.DateTimeField()
I tried write, but failed...
For example:
class DetailView(DetailView):
template_name = 'post.html'
model = Page
def guery_set(self):
return self.request.GET.get('slug')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['posts'] = Page.objects.filter(slug=slug)
return context
And:
class PageView(ListView, SingleObjectMixin):
template_name = 'page_body.html'
paginate_by = 8
def get(self, request, *args, **kwargs):
self.object = self.get_object(
queryset=Category.objects.all())
return super().get(request, *args, **kwargs)
def get_queryset(self):
return Page.objects.filter(category=self.object)
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs)
pages = ????
context['posts'] = pages[:8]
return context