Django : Excluded fields are saved - django

I have a model :
from django.db import models
from tinymce.models import HTMLField
class Team(models.Model):
name = models.CharField(max_length=100, verbose_name='Team name')
city = models.CharField(max_length=100, verbose_name='Team city')
biography = HTMLField(verbose_name='Team biography')
country = models.ForeignKey('Country')
slug = models.SlugField(max_length=100)
def __str__(self):
return self.name
class Country(models.Model):
name = models.CharField(max_length=100, verbose_name='Country name')
code = models.CharField(max_length=5, verbose_name='Country code')
def __str__(self):
return self.code
And a form for this model:
from django import forms
from teams.models import Team
class TeamForm(forms.ModelForm):
class Meta:
model = Team
fields = (
'biography',
'city',
'country'
)
And this is my view:
def add(request):
if request.method == 'POST':
form = TeamForm(request.POST)
if form.is_valid():
send = True
form.save()
else:
form = TeamForm()
return render(request, 'teams/add.html', locals())
As you can see, all my model fields are required because I don't add argument 'null' to True in my model attributes.
In my ModelForm, for testing, I just specify fields biography, city and country.
But when I fill the form and send-it, data are saved in database, however is missing name and slug....
Why dont i have a django exception ?
Thanks for youre help

Neither of those fields are saved as Null, though. They are both character fields (SlugField is a subclass of CharField), and an empty charfield is saved as an empty string - which is perfectly valid from the database point of view.

Related

how to update a extended Django User model?

I have created the user authentication system which includes both the default User model and an extended User model. They are as below:
from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
Photo = models.ImageField(upload_to='documents/%Y/%m/%d/', null=True)
uploaded_at = models.DateTimeField(auto_now_add=True, null=True)
dob = models.DateField(max_length=20, null=True)
country = models.CharField(max_length=100, null=True)
State = models.CharField(max_length=100, null=True)
District = models.CharField(max_length=100, null=True)
phone = models.CharField(max_length=10, null=True)
def get_absolute_url(self):
return reverse('profile', kwargs={'id': self.id})
forms.py
class UserProfileForm(forms.ModelForm):
Photo = forms.ImageField( max_length=100)
dob = forms.DateField(widget=forms.TextInput(attrs={'type': 'date'}))
country = forms.CharField(max_length=100)
State = forms.CharField(max_length=100)
District = forms.CharField(max_length=100)
phone = forms.CharField(max_length=10)
class Meta:
model = UserProfile
fields = ('Photo', 'dob', 'country', 'State', 'District', 'phone')
With the help of the above model and form, I am able to create user, and enter values for those custom model fields and see the user profile. So far so good.
However, I am facing issues while I update those custom fields. I have used the Django's in-built modules to update the default User fields(email). But I am not able to find a way to update those custom fields('dob', 'country', 'State', 'District', 'phone'). Below is the method from views.
views.py
#login_required(login_url="/login/")
def editUserProfile(request):
if request.method == "POST":
form = UserProfileUpdateForm(request.POST, instance=request.user) # default User profile update
obj = UserProfile.objects.get(id=request.user.id)
form1 = UserProfileForm(request.POST or None, instance=obj) # custom fields update.
if form.is_valid() and form1.is_valid():
obj.Photo = form1.cleaned_data['Photo']
obj.dob = form1.cleaned_data['dob']
obj.country = form1.cleaned_data['country']
obj.State = form1.cleaned_data['State']
obj.District = form1.cleaned_data['District']
obj.phone = form1.cleaned_data['phone']
form.save()
form1.save()
messages.success(request, f'updated successfully')
return redirect('/profile1')
else:
messages.error(request, f'Please correct the error below.')
else:
form = UserProfileUpdateForm(instance=request.user)
form1 = UserProfileUpdateForm(instance=request.user)
return render(request, "authenticate\\editProfilePage.html", {'form': form, 'form1': form1})
I have an update button on my profile page, on clicking I could only see the "email" field with pre-populated data to update(I can update this default field successfully).
I have seen other stackoverflow posts, but they are not helping.
I am not able to figure out the mistakes.
Please help
Thank you,
I think the problem is in this line
obj = UserProfile.objects.get(id=request.user.id)
here left id is id from UserProfile model. so it will be something like this
obj = UserProfile.objects.get(user__id=request.user.id)

how to insert foreign key data through Django Model form

How to insert foreign key data through form. Please help . what am I doing wrong. So I have two models as follows :
class Genre(models.Model):
"""Model representing a book genre."""
name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)')
def __str__(self):
"""String for representing the Model object."""
return self.name
ass UserItem(models.Model):
name= models.CharField(max_length = 50, null=True)
genre = models.ForeignKey(Genre, on_delete=models.SET_NULL, null=True)
Forms.py : I want to create form to store Item data. Not able to reference Genre and enter value through form.
class ItemForm(forms.ModelForm):
name = forms.CharField()
genre = forms.CharField()
class Meta:
model = UserItem
fields = ['name', 'genre' ]
Views.py
def item(request):
if request.method == 'POST':
genre_obj = Genre.objects.get(name=request.POST.get('name'))
print("Inside post")
item_form = ItemForm(request.POST)
if item_form.is_valid():
print("valid form")
item_form_obj = ItemForm.save(commit=False)
item_form_obj.genre = genre_obj
item_form_obj.save()
return HttpResponseRedirect(reverse('file_upload') )
else:
print("invalid form")
return HttpResponseRedirect(reverse('file_list') )
genre_obj is a queryset you can not assign queryset to foreignkey field. You can assign objects which is inside the queryset so try this way
item_form_obj.genre = genre_obj[0]
and instead of using HttpResponseRedirect use redirect in both places
from django.shortcuts import redirect
return redirect(reverse('file_upload'))

Django has no object attribute named text - but I don't expect it to?

I have the below structure,
When I click on the model name in the admin view, I get the below error. What does this mean?
AttributeError at /admin/app/tasksx/
'tasksx' object has no attribute 'text'
Request Method: GET
Admin.py
from django.contrib import admin
from .models import tasksx
admin.site.register(tasksx)
Views.py
def create_task(request):
if request.method == 'POST':
creator = request.user
job_title = 'data engineer'
skill_name = request.POST.get('skill_name')
starting = request.POST.get('starting')
description = request.POST.get('description')
target_date = request.POST.get('target_date')
i = tasksx.objects.create(creator=creator, job_title=job_title, skill_name=skill_name, starting=starting, current=starting, description=description, target_date=target_date)
messages.success(request, ('Skill created'))
return redirect('index')
models.py
class tasksx(models.Model):
job_title = models.CharField(max_length=400, default="data")
creator = models.CharField(max_length=400, default="none")
skill_name = models.CharField(max_length=400, default="none")
starting = models.CharField(max_length=400, default="none")
current = models.CharField(max_length=400, default="none")
description = models.CharField(max_length=4000000, default="none")
target_date = models.DateTimeField(default=datetime.now)
def __str__(self):
return self.text
Expanding my comments to avoid extended discussion:
In your tasksx model's __str__ method you are trying to return self.text when you don't have a text field anywhere in the model.
If you want to display the title, modify the method's return to.
def __str__(self):
return self.job_title
Now, if you want to see all fields in the admin interface, you would need to modify your app's admin.py.
admin.py
from django.contrib import admin
from .models import tasksx
class Tasksx_Admin(admin.modelAdmin):
# Add whatever fields you want to display in the admin
# in list_diplay tuple.
list_display = ('job_title', 'creator', 'skill_name', 'starting', 'current', 'description', 'target_date', )
# Register the Taskx_Admin class.
admin.site.register(tasksx, Taskx_Admin)
In the tasksx model you defined:
def __str__(self):
return self.text
But there is no text property in the model.

How to save MultipleChoiceField to db

I want to create a settings page where a user can select multiple values of skills they have. It will have a main category and then subcategories. I need to save those into my database, so I can query them and show their selected skillset again.
I know how to create the MultipleChoiceField but not how to save them to the database. How would I go on about that?
Forms.py
from django import forms
class skills(forms.Form):
jobs = [
('Håndværker', (
('Gulv', 'Gulv'),
('Væg', 'Væg'),
)
),
('Murer', (
('Mur', 'Mur'),
('blabla', 'blabla'),
)
),
]
job = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
choices=jobs)
Views.py
from .forms import skills
def index(request):
if request.method == 'POST':
form = skills(request.POST)
if form.is_valid():
picked = form.cleaned_data.get('job')
# do something with your results
else:
form = skills
return render(request, 'settings/index.html', {"form":form})
It currently looks like this when the page loads which is good. Next step is just how I would save it to the database, so I can display this again with their previous chosen values.
Since you don't have any models setup yet, you can look into django-multiselectfield, which would store the selected choices "as a CharField of comma-separated values". Then you'd just need to pass those values from your form.
Alternatively you can look into PostgreSQL's Array field.
I would recommend you have a Jobs model and a Skills Model. Then have a skills field on the job model which will be a ManyToManyField to the Skills model. The form for this can then be autogenerated for you by Django as a ModelForm.
# Create your models here.
class Skill(models.Model):
name = models.CharField(max_length=20, null=False, blank=False)
def __str__(self):
return self.name
class Job(models.Model):
name = models.CharField(max_length=20, null=False, blank=False)
skills = models.ManyToManyField(Skill)
def __str__(self):
return self.name
class Person(models.Model):
name = models.CharField(max_length=20, null=False, blank=False)
skills = models.ManyToManyField(Skill)
def __str__(self):
return self.name
You can then add them to the db as
skill1 = Skill.objects.create(name="Skill One")
skill2 = Skill.objects.create(name="Skill Two")
skill3 = Skill.objects.create(name="Skill Three")
skill4 = Skill.objects.create(name="Skill Four")
job1 = Job.objects.create(name="Job One")
job1.skills.add(skill1)
job1.skills.add(skill2)
job2 = Job.objects.create(name="Job Two")
job2.skills.add(skill3)
job2.skills.add(skill4)
Have a form to display
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ["name", "skills"]
You can cutomize the form or the template to your linking
in models.py just create the field with CharField
from django.db import models
class UserProfileInfo(models.Model):
Gender = models.CharField(max_length=10,default='')
in forms.py just create CHOICE like below
class UserProfileInfoForm(forms.ModelForm):
YESNO_CHOICES = (('male', 'male'), ('female', 'female'))
Gender = forms.ChoiceField(choices=YESNO_CHOICES)
class Meta():
model = UserProfileInfo
fields = ('Gender',)
in views.py import this form and display it.
or you can definitely go with
https://pypi.org/project/django-multiselectfield/

Django forms(not ModelForms): pre-populate checkbox data from model onto forms

I am trying using django forms and not model forms. While trying to populate data for edit I keep getting keyError (u 'manager'). This does not appear if I remove assignment of a field 'choices'. Choice is a many to many field on my model. to make it less confusing I will paste my model, forms and view.
#model.py
class Choices(models.Model):
choices = models.CharField(max_length=70)
def __unicode__(self):
return self.choices
class UserProfile(models.Model):
user = models.OneToOneField(MyUser)
about_me = models.TextField(max_length=2000, null=True, blank=True)
country = models.CharField(max_length=100,null=True, blank=True)
choices = models.ManyToManyField(Choices, blank=True)
#forms.py
class UserProfileForm(forms.Form):
CHOICES = (
('like to cook', 'like to cook'),
('like only to eat', 'like only to eat')
)
about_me = forms.CharField(widget=forms.Textarea, required=False)
country = forms.CharField(max_length=60,required=False)
choices =forms.MultipleChoiceField(choices=CHOICES,widget=forms.CheckboxSelectMultiple(),required=False)
#views.py
#login_required
def update_profile(request):
userprofile = UserProfile.objects.get(user=request.user)
form = UserProfileForm(initial={'about_me':userprofile.about_me,
'country':userprofile.country,
'choices': userprofile.choices})
return render(request, 'u_profiles/edit_pro.html', {'form':form})
now when I assign the initial value of selected choices I get the keyerror. I would like to know the correct way of doing this.
Thanks.