I have three modelforms and I am trying to validate those forms in a single view. All forms are connected with OneToOne relation. I cannot validate subforms after main form ins same view. Tried few solutions and I guess I am doing something wrong and if someone can help I can redo it few times to understand it at my end. DoctorForm works fine but I couldn't find a suitable method to validate DoctorQualificationForm() and WorkExperienceForm(). Following is the code:
Models:
class User(AbstractUser):
ACC_TYPE = (
('', ''),
('Doctor', 'Doctor'),
('Patient', 'Patient')
)
account_type = models.CharField(max_length=20, choices=ACC_TYPE, null=True, blank=True)
cell_phone = models.IntegerField(null=True, blank=True)
landline = models.IntegerField(null=True, blank=True)
pic = models.ImageField(upload_to='profile/', null=True, blank=True)
secondary_email = models.EmailField(null=True, blank=True)
def __str__(self):
return str(self.username)
def get_absolute_url(self):
return reverse('user:detail', kwargs={'pk':self.user.pk})
class Role(models.Model):
LAB_ADMIN = 1
SALES_ADMIN = 2
SALES_EXCUTIVE = 3
LAB_TECH = 4
ROLE_CHOICES = (
(LAB_ADMIN, 'Lab Admin'),
(SALES_ADMIN, 'Sales Admin'),
(SALES_EXCUTIVE, 'Sales Executive'),
(LAB_TECH, 'Lab Tech'),
)
id = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, primary_key=True)
doctor = models.OneToOneField('Doctor', on_delete=models.CASCADE, related_name='roles')
def __str__(self):
return self.id
class Doctor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='doctor', null=True)
about = models.TextField()
#role = models.OneToOneField(Role, on_delete=models.CASCADE, related_name='currentrole',null=True, blank=True)
street = models.CharField(max_length=200)
city = models.CharField(max_length=200)
country = models.CharField(max_length=200)
cell_phone = models.CharField(max_length=200)
landline = models.CharField(max_length=200)
def __str__(self):
return str(self.user)
def get_absolute_url(self):
return reverse('doctor:detail', kwargs={'pk':self.pk})
class Qualitifaction(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE,
related_name='qualifications')
course_title = models.CharField(max_length=100)
institute_name = models.CharField(max_length=200)
location = models.CharField(max_length=200)
start_year = models.DateField(null=True)
end_year = models.DateField(null=True)
def __str__(self):
return self.course_title
def get_absolute_url(self):
return reverse('doctor:detail', kwargs={'pk':self.pk})
class WorkExperience(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE,
related_name='experience')
organization_name = models.CharField(max_length=100)
year_from = models.DateField(null=True)
year_to = models.DateField(null=True)
employement_role = models.CharField(max_length=200)
industry = models.CharField(max_length=200)
def __str__(self):
return self.organization_name
def get_absolute_url(self):
return reverse('doctor:detail', kwargs={'pk':self.pk})
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
if instance.account_type=='Employee':
profile = Employee.objects.get_or_create(user=instance)
elif instance.account_type=='Customer':
profile = Customer.objects.get_or_create(user=instance)
post_save.connect(update_user_profile, sender=User)
Forms:
class DoctorForm(forms.ModelForm):
model = Doctor
fields = ('about', 'street', 'city', 'country', 'cell_phone', 'landline',)
class DoctorQualificationForm(forms.ModelForm):
model = Qualitifaction
fields = ('course_title', 'institute_name', 'location', 'start_year', 'end_year')
class WorkExperienceForm(forms.ModelForm):
model = WorkExperience
fields = ('organization_name', 'year_from, 'year_to', 'employement_role', 'industry')
View:
def createDoctor(request):
if request.method == 'POST':
doctorform = DoctorForm(request.POST, instance=request.user.doctor)
qualifications_form = DoctorQualificationForm()# not sure how to ref instance here
workexperience_form = WorkExperienceForm()# not sure how to ref instance here
if doctorform.is_valid() and qualifications_form.is_valid() and workexperience_form.is_valid():
doctorform.save()
qualifications_form.save()
workexperience_form.save()
else:
doctorform = DoctorForm()
qualifications_form = DoctorQualificationForm()
workexperience_form = WorkExperienceForm()
return render(request, 'doctor/create.html', {'doctorform':doctorform, 'qualifications_form':qualifications_form, 'workexperience_form':workexperience_form})
def createDoctor(request):
if request.method == 'POST':
doctorform = DoctorForm(request.POST, instance=request.user.doctor)
qualifications_form = DoctorQualificationForm(request.POST)# not sure how to ref instance here
workexperience_form = WorkExperienceForm(request.POST)
if doctorform.is_valid() and qualifications_form.is_valid() and workexperience_form.is_valid():
doctor = doctorform.save()
qualification = qualifications_form.save(commit=False)
qualification.doctor = doctor
qualification.save()
work = workexperience_form.save(commit=False)
work.doctor = doctor
work.save()
else:
doctorform = DoctorForm()
qualifications_form = DoctorQualificationForm()
workexperience_form = WorkExperienceForm()
return render(request, 'doctor/create.html', {'doctorform':doctorform, 'qualifications_form':qualifications_form, 'workexperience_form':workexperience_form})
Although there are number of other ways to do it. But in case you have OneToOne rel in all models you just need to use validation of single or parent model. You can reference that validation in all the children as above.
Related
I trying to do a check In System where Students can do it themselves by inputting their ID's but I am really struggling.
Follow views, models, forms, and html
VIEW
class Attendance(CreateView):
template_name = 'homepage.html'
model = GetAttendance
fields = ['aluno']
success_msg = "Check In Succesfully"
def form_valid(self, form):
form.save()
success_msg = self.get_success_message(form.cleaned_data)
if success_msg:
messages.success(self.request, success_msg)
return super().form_valid(form)
def get_success_url(self):
return reverse('attendance:homepage')
def get_success_message(self, cleaned_data):
return self.success_msg % cleaned_data
MODELS
class Aluno(models.Model):
id = ShortUUIDField(primary_key=True, editable=False, alphabet="0123456789", length=5)
photo = models.ImageField(upload_to='photos/', default='static/images/defaultuser.jpeg', blank=True)
nome = models.CharField(max_length=255)
phone = models.CharField(max_length=255)
email = models.EmailField(max_length=255, unique=True)
location = models.ForeignKey(MasterUser, on_delete=models.CASCADE)
belt = models.CharField(max_length=255, choices=BELT)
stripe = models.CharField(max_length=255, choices=GRAU)
join_date = models.DateField(default=timezone.now)
last_graduation = models.DateField(default=timezone.now)
gender = models.CharField(max_length=255, choices=GENDER)
def __str__(self):
return self.nome
class GetAttendance(models.Model):
aluno = models.ForeignKey(Aluno, on_delete=models.CASCADE)
attendance = models.DateTimeField(default=timezone.now)
def __str__(self):
return str(self.aluno) + ' - ' + str(self.attendance)
That's views.py
My models.py
forms
html
check in page
Basically what I need is instead of having the form of a choice be able to input the student ID and run the model GetAttendance.
I have a form class (incorrect) :
class TeamGoalForm(ModelForm):
class Meta:
employees = forms.ModelMultipleChoiceField(queryset=Employee.objects.filter(departament=Department.objects.get(manager=Manager.objects.get(end_user_id = request.user.username.upper())),widget=forms.CheckboxSelectMultiple()))
department = forms.ModelChoiceField(queryset=Department.objects.all())
model = TeamGoal
fields = '__all__'
widgets = {
'employees' : forms.Select(attrs={'class': 'form-control', 'placeholder':'Select employees'}),
}
'department':forms.Select(attrs={'class': 'form-control', 'placeholder':'Select department'}),
I want to pass parameter request.user.username.upper() which I have in my view.py. How to implement this in my TeamGoalForm?
my view.py
#login_required(login_url='login')
def add_team_goal(request):
form = TeamGoalForm(is_manager(request))
if request.method == 'POST':
form = TeamGoalForm(request.POST)
if form.is_valid():
form.save()
return redirect('team_goal')
team = get_team(request)
if team.exists():
return render(request, 'smth.html', {'form':form,'team':team})
My Employee model:
# Employee section
class Employee(models.Model):
name = models.CharField(max_length=30, verbose_name='Name')
lastname = models.CharField(max_length=30, verbose_name='Lastname')
.............
history = HistoricalRecords()
def __str__(self):
return self.name + ' ' + self.lastname
My Department:
class Department(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=30)
.........
manager = models.ForeignKey(Manager, related_name='manager_name', null=True, on_delete = models.SET_NULL)
history = HistoricalRecords()
My Managers:
class Manager(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
lastname = models.CharField(max_length=30)
history = HistoricalRecords()
def __str__(self):
return self.name + ' ' + self.lastname
My TeamGoal:
class TeamGoal(models.Model):
team_goal_title = models.CharField(max_length=30, verbose_name='Title')
team_goal_description = models.CharField(max_length=100, blank=True, verbose_name='Description')
department = models.ForeignKey(Department, verbose_name='Department', on_delete = models.CASCADE, related_name='+', blank=True, null=True, help_text=u'If you assign the team goal for the whole department, please fill only Department field and skip Employee field.')
employees = models.ManyToManyField(Employee, null=True, blank=True, symmetrical=False, related_name='employee_name')
......
history = HistoricalRecords()
In my app I can create Team goal for whole department or for specific group of employees.
I would really advise not to give Manager the same name as a user and then match on that: it makes keeping records in sync quite hard. You can link to the user model with:
from django.conf import settings
class Manager(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
history = HistoricalRecords()
def __str__(self):
return f'{self.user.first_name} {self.user.lastname}'
you can pass the user as parameter to the ModelForm and then filter the queryset:
class TeamGoalForm(ModelForm):
def __init__(self, *args, user=None, **kwargs):
super().__init_(*args, **kwargs)
if user is not None:
self.field['employees'] = Employee.objects.filter(
department__manager__user=user
)
class Meta:
model = TeamGoal
fields = '__all__'
widgets = {
'employees' : forms.SelectMultiple(attrs={'class': 'form-control', 'placeholder':'Select employees'}),
'department':forms.SelectMultiple(attrs={'class': 'form-control', 'placeholder':'Select department'})
}
and in the view pass the logged in user to the TeamGoalForm:
#login_required(login_url='login')
def add_team_goal(request):
if request.method == 'POST':
form = TeamGoalForm(request.POST, user=request.user)
if form.is_valid():
form.save()
return redirect('team_goal')
else:
form = TeamGoalForm(user=request.user)
team = get_team(request)
return render(request, 'smth.html', {'form':form,'team':team})
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 am making a CV page,
I want to link my Skill, Language etc class(table) to Main Person table/class,
But for that, I need to submit skill table first because my person table contains the foreign key for skills.
But as per CV form name & personal info comes first.
Also, I can put the whole form on one page but I want to go to the next page for each sub information, so is it possible to pass the request data from one class-based view to another class-based view.
models.py
from django.db import models
from django.core.validators import MinLengthValidator
from django.conf import settings
import datetime
class Workexperience(models.Model):
work = models.CharField(null=True, blank=True,
max_length=256,
help_text='eg: Juniorengineer: at L&T ')
person = models.ForeignKey('Person', on_delete=models.CASCADE, blank=True, null=False, default=1 )
def __str__(self):
return self.work
class Education(models.Model):
school = models.CharField(max_length=200)
college = models.CharField(null=True, blank=True,max_length=200)
person = models.ForeignKey('Person', on_delete=models.CASCADE, blank=True, null=False, default=1 )
def __str__(self):
return self.school
class Skills(models.Model):
skill = models.CharField(
max_length=256,
help_text='Add skills sperated by commas eg: programming, Matlab')
person = models.ForeignKey('Person', on_delete=models.CASCADE, blank=True, null=False, default=1 )
def __str__(self):
return self.skill
class Languages(models.Model):
language = models.CharField(
max_length=256,
help_text='Add language sperated by commas eg: English, Gujarati')
person = models.ForeignKey('Person', on_delete=models.CASCADE, blank=True, null=False, default=1 )
def __str__(self):
return self.language
class Person(models.Model):
name = models.CharField(
max_length=100,
help_text='Enter a name (e.g. Harry Virani)',
validators=[MinLengthValidator(2, "It must be greater than 1 character")]
)
picture = models.BinaryField(null=True, blank=True, editable=True)
content_type = models.CharField(max_length=256, null=True, blank=True,
help_text='The MIMEType of the file')
profession = models.CharField(
max_length=100,
validators=[MinLengthValidator(2, "It must be greater than 1 character")]
)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default='')
address = models.CharField(max_length=256)
email = models.EmailField(max_length = 254)
phone = models.CharField(
max_length=15,
help_text='Enter a phone number like this (e.g. +91000000000)',
validators=[MinLengthValidator(10, "It must be greater than 10 character")] )
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
facebook = models.URLField(null=True, blank=True, max_length=200,
help_text='enter your facebook URL' )
instagram = models.URLField(null=True, blank=True, max_length=200,
help_text='enter your instagram link URL' )
linkedin = models.URLField(null=True, blank=True, max_length=200,
help_text='enter your Linked link URL' )
skill = models.ManyToManyField(Skills, related_name='skills', default=1)
language = models.ManyToManyField(Languages, related_name='languages', default=1)
edu = models.ManyToManyField(Education, default=1,related_name='edu' )
work = models.ManyToManyField(Workexperience,default=1, blank=True, related_name='works')
# Shows up in the admin list
def __str__(self):
return self.name
views.py
I want to save it in another class which is for creating skill & other models.
class PersonCreateView(LoginRequiredMixin, View):
template_name = 'MYP/form.html'
success_url = 'MYP:myp_create_info'
def get(self, request, pk=None):
personform = PersonForm()
ctx = { 'personform': personform}
return render(request, self.template_name, ctx)
def post(self, request, pk=None) :
# if 'personform' in request.POST:
personform = PersonForm(request.POST, request.FILES or None)
if not personform.is_valid():
ctx = {'personform': personform}
return render(request, self.template_name, ctx)
pform = personform.save(commit=False)
#adding onwer
pform.owner = self.request.user
pform.save()
return redirect(self.success_url, pform.id)
class InfoCreateView(LoginRequiredMixin, View):
template_name = 'MYP/form2.html'
success_url = reverse_lazy('MYP:all')
def get(self, request, pk):
person = get_object_or_404(Person,id=pk)
skill= SkillsForm()
skill_list = Skills.objects.filter(person=person)
ctx = { 'skill':skill, 'skill_list':skill_list }
return render(request, self.template_name, ctx)
def post(self, request, pk):
if 'skill' in request.POST:
skill = SkillsForm(request.POST or None)
if not skill.is_valid() :
ctx = { 'skill':skill}
return render(request, self.template_name, ctx)
person = get_object_or_404(Person,id=pk)
print(person)
skill = Skills(skill=request.POST['skill'], person=person)
skill.save()
print(skill.person)
return redirect('MYP:myp_create_info', pk=pk)
forms.py
class PersonForm(forms.ModelForm):
max_upload_limit = 2 * 1024 * 1024
max_upload_limit_text = naturalsize(max_upload_limit)
# Call this 'picture' so it gets copied from the form to the in-memory model
# It will not be the "bytes", it will be the "InMemoryUploadedFile"
# because we need to pull out things like content_type
picture = forms.FileField(required=False, label='File to Upload <= '+max_upload_limit_text)
upload_field_name = 'picture'
# Hint: this will need to be changed for use in the ads application :)
class Meta:
model = Person
fields = ['name', 'profession', 'picture', 'address', 'email', 'phone','facebook','linkedin','instagram'] # Picture is manual
# Validate the size of the picture
def clean(self) :
cleaned_data = super().clean()
pic = cleaned_data.get('picture')
if pic is None : return
if len(pic) > self.max_upload_limit:
self.add_error('picture', "File must be < "+self.max_upload_limit_text+" bytes")
# Convert uploaded File object to a picture
def save(self, commit=True) :
instance = super(PersonForm, self).save(commit=False)
# We only need to adjust picture if it is a freshly uploaded file
f = instance.picture # Make a copy
if isinstance(f, InMemoryUploadedFile): # Extract data from the form to the model
bytearr = f.read();
instance.content_type = f.content_type
instance.picture = bytearr # Overwrite with the actual image data
if commit:
instance.save()
return instance
class WorkexperienceForm(forms.ModelForm):
class Meta:
model = Workexperience
fields = ['work']
class EducationForm(forms.ModelForm):
class Meta:
model = Education
fields = ['school','college']
class SkillsForm(forms.ModelForm):
class Meta:
model = Skills
fields = ['skill']
class LanguagesForm(forms.ModelForm):
class Meta:
model = Languages
fields = ['language']
Ignore the rest of the code it is just for image handling....
This is what I want to do but I know it is the wrong format
I want to just add id for everything later.
In my opinion, your models are messed up. Here is how I would have write them :
class WorkExperience(models.Model):
work = models.CharField(
blank=True,
max_length=256,
help_text='eg: Juniorengineer: at L&T'
)
def __str__(self):
return self.work
class Education(models.Model):
school = models.CharField(max_length=200)
college = models.CharField(blank=True, max_length=200)
def __str__(self):
return self.school
class Skill(models.Model):
name = models.CharField(
max_length=256,
help_text='Add a skill name (eg: Programming)'
)
def __str__(self):
return self.name
class Language(models.Model):
name = models.CharField(
max_length=256,
help_text='Add a language name (eg: Gujarati)'
)
def __str__(self):
return self.name
class Person(models.Model):
name = models.CharField(
max_length=100,
help_text='Enter a name (e.g. Harry Virani)',
validators=[MinLengthValidator(2, "It must be greater than 1 character")]
)
# [...Other fields...]
skills = models.ManyToManyField(Skill, related_name='persons', blank=True)
languages = models.ManyToManyField(Language, related_name='persons', blank=True)
educations = models.ManyToManyField(Education, related_name='persons', blank=True)
work_experiences = models.ManyToManyField(WorkExperience, related_name='persons', blank=True)
def __str__(self):
return self.name
Then I need to see your forms.py to better understand how you handle it in your view.
I'm trying to create a writable nested serializer.
I read django rest documents but in my case i have multiple nested fields and don't know how can solve that i get this error:
TypeError at /api/v1/libraries/
'tel_number' is an invalid keyword argument for this function
models.py:
class RegisterRule(models.Model):
picture = models.BooleanField(default=False)
passport = models.BooleanField(default=False)
education_rule = models.CharField(max_length=255)
class SpecificInformatin(models.Model):
specific_name = models.CharField(max_length=255)
description = models.TextField(max_length=255)
def __unicode__(self):
return self.specific_name
class District(models.Model):
district = models.CharField(max_length=2)
def __unicode__(self):
return self.district
class Address(models.Model):
district = models.ForeignKey(District, on_delete=models.CASCADE)
square = models.CharField(max_length=20)
master_street = models.CharField(max_length=20)
slave_street = models.CharField(max_length=20)
plaque = models.CharField(max_length=3)
def __unicode__(self):
return self.slave_street
class Library(models.Model):
name = models.CharField(max_length=30)
address = models.OneToOneField(Address, on_delete=models.CASCADE, related_name='address')
reading_room = models.BooleanField(default=False)
reading_room_start_time = models.CharField(max_length=10, default='8:00')
reading_room_end_time = models.CharField(max_length=10, default='20:00')
library_start_time = models.CharField(max_length=10, default='8:00')
library_end_time = models.CharField(max_length=10, default='20:00')
specific_information = models.ManyToManyField(SpecificInformatin)
register_rules = models.ManyToManyField(RegisterRule)
gender_days_in_week = models.CharField(max_length=100, default='mens')
manager_of_library = models.CharField(max_length=50, default='shahrdari')
tel_number = models.CharField(max_length=11, null=True)
email = models.EmailField(max_length=40, default="#.com")
from_user = models.BooleanField(default=False)
def __unicode__(self):
return self.name
serializers.py:
class LibrarySerializer(serializers.ModelSerializer):
address = AddressSerializer()
specific_information = SpecificSerializer(many=True)
register_rules = RegisterRulesSerialzers(many=True)
class Meta:
model = Library
fields = ('id', 'name', 'address', 'reading_room', 'reading_room_start_time'
, 'reading_room_end_time', 'library_start_time', 'library_end_time'
, 'specific_information', 'register_rules', 'gender_days_in_week'
, 'manager_of_library', 'tel_number', 'email', 'from_user')
def create(self, validated_data):
address_data = validated_data.pop('address')
address = Address.objects.create(**validated_data)
register_rules_data = validated_data.pop('register_rules')
register_rules = RegisterRule.objects.create(**validated_data)
specific_information_data = validated_data.pop('specific_information')
specific_information = SpecificInformatin.objects.create(**validated_data)
library = Library.objects.create(**validated_data)
library.address(address=address, **address_data)
for data in register_rules_data:
library.register_rules.add(register_rules=register_rules, **data)
for data in specific_information_data:
library.specific_information.add(specific_information=specific_information, **data)
return library
You are doing some mistake. when you pop some data from dict it return value of particular data.
create(self, validated_data):
address_data = validated_data.pop('address')
address = Address.objects.create(**address_data)
register_rules_data = validated_data.pop('register_rules')
specific_information_data = validated_data.pop('specific_information')
library = Library.objects.create(address=address, **validated_data)
for data in register_rules_data:
register_rules = RegisterRule.objects.create(**data)
library.register_rules.add(register_rules)
for data in specific_information_data:
specific_information = SpecificInformatin.objects.create(**data)
library.specific_information.add(specific_information)
return library
I think this code will work for you.