Related
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})
Hello I have such a question about model filtering, I would like to write a filter that will allow me to display individual tournament groups assigned to a given tournament only in the tab related to that tournament.
this is my models.py
class Tournament(models.Model):
data = models.DateField(null=True)
tournament_name = models.CharField(max_length=256, null=True)
tournament_creator = models.ForeignKey(Judges, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.tournament_name
class TournamentGroup(models.Model):
group_name = models.CharField(max_length=256, null=True)
tournament_name = models.ForeignKey(Tournament, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.group_name
class TournamentUsers(models.Model):
user_first_name = models.CharField(max_length=256)
user_last_name = models.CharField(max_length=256)
user_tournament = models.ForeignKey(Tournament, on_delete=models.SET_NULL, null=True)
user_group = models.ForeignKey(TournamentGroup, on_delete=models.SET_NULL, null=True)
def __str__(self):
return self.user_last_name + ' ' + self.user_first_name
and this is my views.py file
def content(request, pk):
tournament = get_object_or_404(Tournament, pk=pk)
tournament_groups = TournamentGroup.objects.filter(tournament_name=tournament)
users = TournamentUsers.objects.filter(user_tournament=tournament)
form = TournamentUsersForm()
if request.method == "POST":
form = TournamentUsersForm(request.POST)
if form.is_valid():
form.save()
form = TournamentUsersForm()
return render(request, 'ksm_app2/content.html', {'tournament': tournament, 'users': users,
'form': form, 'tournament_groups': tournament_groups})
The user filter works correctly after he has chosen the right tournament but I have a problem with the team, I will appreciate any hint
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 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.
I created an album with a photos as foreign key but somehow when i add a photo it does not save probably in my database or admin site
Here are my models:
class AlbumPluginModel(CMSPlugin):
name = models.CharField(max_length=255,
help_text=_('e.g: Zuerich city, or Zuerich Hoengg'))
slug = models.SlugField(_('Slug'), blank=True, null=True, unique=True, db_index=True)
description = HTMLField(blank=True, null=True)
cover_photo = models.ImageField(verbose_name=_('Add cover photo'), null=True, blank=True)
is_active = models.BooleanField(_('active'), blank=True)
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
sort = models.IntegerField(_("Sort Order"), null=True, blank=True, default=0)
def __str__(self):
if self.name:
return u"File for %s" % self.name
else:
return u"%s" % self.name
def get_absolute_url(self):
return "/album_detail%i/" % self.id
class Meta:
ordering = ['sort']
verbose_name = "Album"
verbose_name_plural = "Albums"
class Photo(models.Model):
photo = models.ForeignKey(AlbumPluginModel, verbose_name=_('choose album'), null=True, blank=True)
image1 = models.ImageField(verbose_name=_('Photo'), null=True, blank=True, upload_to="/static/img/")
sort = models.IntegerField(_("Sort Order"), null=True, blank=True, default=0)
def __unicode__(self):
return u"%s" % self.image1
def __str__(self):
return u"%s" % self.image1
class Meta:
ordering = ['sort']
verbose_name = _("photo")
verbose_name_plural = _("Photos")
forms.py
class AlbumPluginForm(forms.ModelForm):
class Meta:
model = AlbumPluginModel
fields = ['name', 'description', 'cover_photo', 'is_active',]
class PhotoPluginForm(forms.ModelForm):
photo = forms.ModelChoiceField(label='select album',aqueryset=AlbumPluginModel.objects.all(), required=False)
class Meta:
model = Photo
fields = ('photo', 'image1', )
views.py
def add_photo(request, id=None, **kwargs):
if request.method == 'POST':
all_photos = Photo.objects.all
form = PhotoPluginForm(request.POST, request.FILES, initial={'photo': id})
template_name = 'photo_create.html'
context = {
"form": form,
"all_photos": all_photos,
}
if form.is_valid():
all_photos = form.save(commit=False),
form.save()
messages.success(request, "Photo was added.")
return redirect('/photos')
else:
print("error: form nicht valid")
return render(request, template_name, context)
You should add upload_to parameter for field in which you want to upload some file in server. In your case, in AlbumPluginModel your cover_photo will be
cover_photo = models.ImageField(verbose_name=_('Add cover photo'), null=True, blank=True, upload_to='path_where_you_want_to_save')
If you call save() with commit=False, then it will return an object that hasn’t yet been saved to the database. In this case, it’s up to you to call save() on the resulting model instance. You should change your view like this
all_photos = form.save(commit=False),
all_photos.save()
after a long try i finally found the answer:
in views.py
i chnaged this line from
form = PhotoPluginForm(request.POST or None)
to:
form = PhotoPluginForm(request.POST, request.FILES)
and in my template i forgot this:
enctype="multipart/form-data"