I'm trying to create my own User class called Customer which extends the AbstractUser model and has an additional field called address. When I register, I see the user has been created in Django admin and all the fields (username, first name, last name and email) are seen in the django admin screen but I see no value in the "address" field. How do I know if the address is being saved and how can I display it in the admin site?
Below is my code for the models.py
class Customer(AbstractUser):
username = models.CharField(unique=True, max_length=20)
deladdress = models.CharField(max_length=100)
views.py
def signupPage(request):
signForm = CreateCustomer()
if request.method=='POST':
signForm = CreateCustomer(request.POST)
if signForm.is_valid():
signForm.save()
return render(request, 'trial_app/signup.html', {'signForm':signForm})
forms.py
class CreateCustomer(UserCreationForm):
address = forms.CharField(widget=forms.Textarea)
class Meta:
model = Customer
fields = ['username','first_name','last_name','email','address','password1','password2']
def save(self, commit=True):
user = super(CreateCustomer, self).save(commit=False)
user.address = self.cleaned_data["address"]
if commit:
user.save()
return user
Here are some pictures that are the input to my html form and the value in the admin site
It seems like when you save a form in its save method you use
user.address = self.cleaned_data["address"], however, Customer model does not have address field, it has deladdress, so try to rename a field, or use user.deladdress in your save method of CreateCustomer form.
Related
check the updated pic
When I save the model, The object name is None, but I need to save the username instead of object name (None) automatically while I saving the Model
here is pic of admin site
Models.py
class solo_21_6_2021(models.Model):
user = models.OneToOneField(User,null=True,on_delete=models.CASCADE)
player1_pubg_id = models.PositiveIntegerField(null=True,blank=True)
player1_pubg_name = models.CharField(max_length=15,null=True,blank=True)
def __str__(self):
return str(self.user)
Views.py
def solo(request):
form = SoloForm()
if request.method=="POST":
form=SoloForm(request.POST)
if form.is_valid():
form.save()
return render(request, 'bgmiapp/solo.html',{'form':form})
Forms.py
class SoloForm(forms.ModelForm):
class Meta():
model = solo_21_6_2021
fields=['player1_pubg_id','player1_pubg_name'
Admin.py
class SoloAdmin(admin.ModelAdmin):
list = ('user','player1_pubg_id','player1_pubg_name')
admin.site.register(Profile)
admin.site.register(solo_21_6_2021,SoloAdmin)
you have set user field to null so the model is created without it, so when you want to show objects by user, it does not have this info so it shows None.
modify models to :
class solo_21_6_2021(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
player1_pubg_id = models.PositiveIntegerField(null=True,blank=True)
player1_pubg_name = models.CharField(max_length=15,null=True,blank=True)
def __str__(self):
return str(self.user)
so now it is required and related as it is supposed to be
and inf the forms:
class SoloForm(forms.ModelForm):
class Meta():
model = solo_21_6_2021
fields=['user','player1_pubg_id','player1_pubg_name']
so it display the choice of user in the html form
now when you submit the form, the user name will display in the admin page
*Alternatively you could make your authenticated user the one who is creating the object, so no need to show list of your users to everyone:
def solo(request):
form = SoloForm()
if request.method=="POST":
form=SoloForm(request.POST)
if form.is_valid():
f = form.save(commit=False)
f.user = request.user
f.save()
return render(request, 'bgmiapp/solo.html',{'form':form})
and get rid of user in forms:
class SoloForm(forms.ModelForm):
class Meta():
model = solo_21_6_2021
fields=['player1_pubg_id','player1_pubg_name']
Ps: since you have a OnetoOne relation, you can create only one object by user, creating another will throw a user_id unique constraint error
trying to create a model that has an artist and song and lets you know what user name typed it in.
so far I have in my models.py
from django.contrib.auth.models import User
class Song(models.Model):
uesrname = models.ForeignKey(User,on_delete=models.CASCADE)
artist = models.CharField(max_length=30)
song=models.CharField(max_length=30)
I added a form that works with user input data but the form lets me select one of all exciting Users and input artist, song
forms.py
class NewSong(forms.ModelForm):
class Meta:
model=Song
exclude = ['username']
how can I change it so I will have only my own loged in user in the form?
You can exclude username field as exclude = ['username'] on your forms.py file and set username to request.user on form's save method. For more information: selecting fields
I'm kinda new to django, I need to set a dynamic initial value to my modelform field. I have a database field in my model name 'author' it has a foreignkey that connects it to the django user model. I need to automatically set this to the current user anytime a user fills in information into the form.
from what I gathered about this problem, I'd have to define an __init__ function inside the MyHouseEditForm below, I'm new to django and all the examples I've seen a pretty confusing.
forms.py
from django import forms
from django.contrib.auth.models import User
from .models import Myhouses
class MyHouseEditForm(forms.ModelForm):
class Meta:
model = Myhouses
fields = ('author','name_of_accomodation', 'type_of_room', 'house_rent', 'availability', 'location', 'nearest_institution', 'description', 'image')
i need to set the value of 'author' to the current user anytime a user logs in.
models.py
from django.db import models
from django.contrib.auth.models import User
class Myhouses(models.Model):
author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='author')
Available = 'A'
Not_Available = 'NA'
Availability = (
(Available, 'Available'),
(Not_Available, 'Not_Available'),
)
name_of_accomodation = models.CharField(max_length=200)
type_of_room = models.CharField(max_length=200)
house_rent = models.IntegerField(null=True)
availability = models.CharField(max_length=2, choices=Availability, default=Available,)
location = models.CharField(max_length=200)
nearest_institution = models.CharField(max_length=200)
description = models.TextField(blank=True)
image = models.ImageField(upload_to='profile_image')
def __str__(self):
return self.name_of_accomodation
views.py
#login_required
def addlisting(request):
if request.method == 'POST':
form = MyHouseEditForm(request.POST, files=request.FILES)
if form.is_valid():
Houses = form.save(commit=False)
Houses.save()
return redirect('addlisting')
else:
form = MyHouseEditForm()
return render(request, 'houses/addlisting.html', {'form':form })
No need to show author field in form. It would automatically populate with logged in user.
request.user gives you logged in user object. So, you may remove 'author' filed from forms field section and do this:
Houses = form.save(commit=False)
Houses.author = request.user
Houses.save()
I did something like this in the serializer.
I defined a custom create method like this:
class MyhousesSerializer(FlexFieldsModelSerializer):
...
def create(self, validated_data):
validated_data['author'] = self.context['request'].user
newhouse = Myhouses.objects.create(**validated_data)
return newhouse
It shouldn't matter if you use a more regular model serializer.
Here i have two models:
ProfilePic
Member
ProfilePic's user variable extends from Member's username (this is so i can have one username in the DB for all other forms and models).
Now ProfilePic is used as a form, and in my views.py I want to add:
member_obj = Member.objects.get(pk=username)
to my ProfilePic form. However, when I run my code, it doesn't give an error but it doesn't render the information in the db either. So I'm confused as to whats going on here.
What am i doing wrong? Thanks in advance !
# models.py
class ProfilePic(models.Model):
user = models.ForeignKey(Member, related_name='%(class)s_user', null=True)
text = models.TextField(max_length=4096)
thumbnail = models.FileField(upload_to='media', null=True)
class Member(models.Model):
username = models.CharField(max_length=16, primary_key=True)
password = models.CharField(max_length=16)
profile = models.OneToOneField(Profile, null=True)
following = models.ManyToManyField("self", symmetrical=True)
# forms.py
from django import forms
from .models import ProfilePic
class UploadFileForm(forms.ModelForm):
class Meta:
model = ProfilePic
fields = ['text','thumbnail']
# views.py
def profile(request):
username = request.session['username']
member_obj = Member.objects.get(pk=username)
if request.POST:
invitations = Invitation.objects.filter(to_user=username)
form = UploadFileForm(request.POST,request.FILES, instance=member_obj)
form.save()
picture = ProfilePic.objects.all()
return render(request, 'social/profile.html', {
'appname': appname,
'username': username,
'invitations':invitations,
'picture' : picture,
'form' : form,
'loggedin': True}
)
You are passing a Member instance to a ProfilePic model form.
What you want to do is:
form = UploadFileForm(request.POST, request.FILES,
instance=member_obj.profile_pic_user)
So you get a ProfilePic instance.
View is just a function. You get a Member object from the database, assign it to a member_obj variable, but you are not actually doing anything with it. You want to assign it to a ProfilePic object. Also, I don't think this line picture = ProfilePic.objects.all() does what you intend to do. You are getting a list of all profile picture objects instead of just one.
You have to add it to the saved object. You do that by telling the form to create the object, but not saving it to the DB yet.
Then, set the field, and save to the DB.
Add this lines to the view, instead of the form.save():
profile_pic = form.save(commit=False) #not saving to db
member_obj = Member.objects.get(username=request.user.username)
profile_pic.user = member_obj
profile_pic.save() # now it's saved
I have a User Model (pre-defined by Django) and a UserProfile model connected via a ForeignKey.
I'm creating two separate ModelForms to use in a single template as a registration form of sorts.
models.py
class UserProfile(models.Model):
# This field is required.
user = models.ForeignKey(User, unique=True, related_name="connector")
location = models.CharField(max_length=20, blank=True, null=True)
forms.py
class UserForm(ModelForm):
class Meta:
model = User
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
However, when I load the page and fill in the form information, the UserProfileForm requires me to select / fill in the user field in order to validate.
This "user", however, is the one that is being created right now so I can't choose a "user" as it has not been created yet / is still being created.
I know this user is field has the attribute unique=true but there a way to make this field "optional"?
My view (below) should handle it such that once the user object is created, i will set the foreign key of UserProfile to this newly created user object (unless I am doing something wrong my views.py as well).
views.py
#csrf_protect
def register(request):
if request.method == 'POST':
form1 = UserForm(request.POST)
form2 = UserProfileForm(request.POST)
if form1.is_valid() and form2.is_valid():
#create initial entry for user
username = form1.cleaned_data["username"]
password = form1.cleaned_data["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
#create entry for UserProfile (extension of new_user object)
profile = form2.save(commit = False)
profile.user = new_user
profile.save()
return HttpResponseRedirect("/books/")
else:
form1 = UserForm()
form2 = UserProfileForm()
c = {
'form1':form1,
'form2':form2,
}
c.update(csrf(request))
return render_to_response("registration/register.html", c)
Well you could set:
user = models.ForeignKey(User, unique=True, blank=True, null=True, related_name="connector")
which would make the user relationship optional, but I don't think this is what you need. Instead, why not just remove the user field from the UserProfile form and manually assign it, instead of letting the user see the dropdown at all. Then there would be no validation error.
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
exclude = ("user", )
Simply exclude the field from the form.
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
exclude = ('user',)