i created a model
class ThisUser(models.Model):
created = models.DateTimeField(auto_now=True)
message = models.CharField(max_length=120)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.user
I want to store message specifically for the user who is authenticated.
right now this will give me all user who is available in my user model.
Please help
user = models.OneToOneField(User, on_delete=models.CASCADE)
Instead of foriegn key use one to one relation
Well you are suppose to take care of that at view level and not model level,
for example this is how I create a new Album:
#login_required
def make_album(request):
if request.method == 'POST':
form = AlbumCreationForm(request.POST)
if form.is_valid():
new_album = core_models.Album(name=form.cleaned_data['name'], description=form.cleaned_data['description'], user=request.user)`
You can use request.user.id to get user's id for further use.
Related
I have a form in my django website where the user requests coins and the information is sent to the admin for me to process. I want to automatically get the user who filled the form without them doing it themselves.
Here's the model.py file:
class Requestpayment (models.Model):
username= models.ForeignKey(User, on_delete= models.CASCADE, null=True)
useremail= models.CharField(max_length=100)
accountmail= models.CharField(max_length=100)
accountphonenumber=models.CharField(max_length=15)
coinsrequested=models.ForeignKey(Requestamount, on_delete= models.SET_NULL, null=True)
created= models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.accountmail
the forms.py:
class Requestpaymentform (ModelForm):
class Meta:
model = Requestpayment
fields = '__all__'
and the views.py:
#login_required(login_url='login')
def redeemcoins (request):
form = Requestpaymentform
if request.method =='POST':
form = Requestpaymentform(request.POST)
if form.is_valid():
form = form.save(commit=False)
username = request.user
form.save()
return redirect ('home')
I am pretty sure something is wrong but i don't know what it is (I'm very new at django) anyway the form always shows all the users in the website for the current user to pick who they are.
redeem coins page
I also tried excluding that part of the form but it didn't work it just shows up empty in the admin.
thank you.
You need to assign it to the instance wrapped in the form, so:
#login_required(login_url='login')
def redeemcoins(request):
form = Requestpaymentform()
if request.method == 'POST':
form = Requestpaymentform(request.POST)
if form.is_valid():
form.instance.username = request.user
form.save()
return redirect('home')
# …
It makes more sense however to name this field user than username. In the model you can also make the username field non-editable, such that it does not appear in the form:
from django.conf import settings
class Requestpayment(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL, editable=False, on_delete=models.CASCADE
)
# …
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
When you use username= models.ForeignKey(User, on_delete= models.CASCADE, null=True), Django add a field named user_id in your database which allow django to find User object for Requestpayment.
You can use user_id field to add a User object in Requestpayment.
You don't need to pass username field in your fields list if you want to get user in view.
class Requestpaymentform (ModelForm):
class Meta:
model = Requestpayment
#fields = '__all__'
fields = ['useremail',
'accountmail',
'accountphonenumber',
'coinsrequested',
'created']
Now do this to get user in your view.
#login_required(login_url='login')
def redeemcoins(request):
form = Requestpaymentform()
if request.method == 'POST':
form = Requestpaymentform(request.POST)
if form.is_valid():
requestpayment = form.save(commit=False)
requestpayment.user_id = request.user.id
requestpayment.save()
return redirect('home')
And it's great to use user instead username because it's a User object and not a simple field.
Please for my English !!!
so I'm trying to build a Ledger App. When new users sign-ups, they create a new Business account that is linked to them (ForeignKey). Here is my model:
User = get_user_model()
class Business_Account(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
business_name = models.CharField(max_length=50)
Type_of_service = models.CharField(choices=SERVICE_CATEGORIES, max_length=50)
business_email_address = models.EmailField(max_length=254)
class Meta:
verbose_name = "Business_Account"
verbose_name_plural = "Business_Accounts"
def __str__(self):
return self.business_name
Now, I want to make a get request view that can query and returns a business account that belongs to a particular user. My current view just returns all the business accounts available in the database irrespective of which user is login. Here is my view:
class AddBusinessAcctView(APIView):
def get_object(self):
try:
return Business_Account.objects.all()
except:
raise status.HTTP_404_NOT_FOUND
def get(self,request):
queryset = self.get_object()
serializer = BusinessAcctSerializer(queryset, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
Now, How can I query business accounts that belong to a particular user?. Thanks in advance
Normally, you'd have authentication and a logged-in user that you were trying to retrieve information for. Assuming you're going to do this, that user is available in the request object.
Business_Account.objects.get(user=request.user)
But in general, you can just do:
user = User.objects.get(username='john')
Business_Account.objects.get(user=request.user)
# or
Business_Account.objects.get(user_id=123456)
I finally got it. It is something similar to the above answer.
queryset = Business_Account.objects.filter(user=request.user)
Thanks in advance if you're reading this... I'm a High School student working on a web application using Django, to help students find internships, and facilitate parents posting internship offers -- a sort of marketplace if you will.
I'm trying to create a profile/account page for the users but I need a way to differentiate between whether the account logged in is a Student or Employer so that I can use views.py to generate a page appropriate to their account.
In models.py, I have two different profile types which can be associated with a user account (handled by django.contrib.auth), see below for reference.
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profilePic = models.ImageField(default='default.jpg', upload_to='profile_pics')
class Meta:
verbose_name = 'Student Profile'
def __str__(self):
return f"{self.user.username}'s Profile"
class Employer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profilePic = models.ImageField(default='default.jpg', upload_to='profile_pics')
company = models.CharField(max_length=100, default='Unspecified')
class Meta:
verbose_name = 'Employer/Parent Profile'
def __str__(self):
return f"{self.user.username}'s Profile"
In my views.py page, I'm trying to create a view for the account/profile that can detect whether the currently logged-in user's profile is linked to either the 'Student' or 'Parent' model and serve a page accordingly. I've tried a very rudimentary approach, as below, but unsurprisingly it's not working.
def account(request):
if user.student.username == True:
context = 'Account: Student'
return render(request, 'users/studentprofile.html', context)
elif user.employer.username == True:
context = 'Account: Employer'
return render(request, 'users/employer.html', context)
I was wondering if anyone had a suggestion as to how I can best accomplish this... apologies in advance is this approach is poorly structured or against the status-quo of Django Programming, I'm a complete beginner!
Thanks in advance all :)
As Morteza Afshari said, you should reorganize your models to include a boolean field.
class CustomUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profilePic = models.ImageField(default='default.jpg', upload_to='profile_pics')
is_student = models.BooleanField(default=True)
class Meta:
verbose_name = 'Profile'
def __str__(self):
return f"{self.user.username}'s Profile"
This follows the DRY principle much better than your prior code because now we're not repeating fields like user, profilePic, etc.
Now we can rewrite your views.py like this:
def account(request):
if user.is_student:
context = 'Account: Student'
return render(request, 'users/studentprofile.html', context)
else:
context = 'Account: Employer'
return render(request, 'users/employer.html', context)
it would be better if you posted your exception/error alongside your code
but here's some hint:
context parameter passed to render function should be a dictionary not an string
context = {'Account: Student'}
and you should access to user with request.user not just user
if problems above didn't solve your problem
add these two lines of code at the beginning of your function:
print(request.user.student)
print(request.user.employer)
You can have an boolean field in user model like is_student and fill it during sign in. It can be null=True and null when user signed out.
If you have jwt token, you can store additional data in token to check where it comes from, or either store user current role in its cookie. Get us more data about your site structure for more related answers. (Data about authentication system, database structure or any more structural behaviors)
I have created a Edit Profile form in my Django app but it doesn't save in the database.
This is the profile model:
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile', primary_key=True) #Each User is related to only one User Profile
city_search_text = models.CharField(blank=True, max_length=300)#user picks a city from autocomplete and in the view I get or create a City object
city = models.ForeignKey(City, blank=True, null=True, related_name='city') #Each User Profile must be related to one city.
prof_pic = models.ImageField(blank=True, upload_to='profile_pictures')
dob = models.DateField(blank=True, null=True)
def __str__(self):
return self.user.first_name
This is the form:
class EditProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('dob',)#I'm testing to update this field only
def save(self, commit=True):
profile = super(EditProfileForm, self).save(commit=False)
if commit:
profile.save()
return profile
This is the view:
def editprofile(request):
if request.method == 'POST':
edit_profile_form = EditProfileForm(request.POST, instance=request.user)
if edit_profile_form.is_valid():
profile = edit_profile_form.save(commit=False)
profile.save()
if 'next' in request.GET:
return redirect(request.GET['next'])
else:
print (profile_form.errors)
else:
edit_profile_form = EditProfileForm(instance=request.user.profile)
return render(request, 'excurj/editprofile.html', {'edit_profile_form':edit_profile_form,})
After I submit the form it forwards me to index page okay but the values remain the same in the user's profile.
Seems like
if edit_profile_form.is_valid():
isn't getting called at all, and your data is not saved. That means your form has invalid data, and you should check for form errors to detect those.
Also, you are trying to print form errors if the request isn't POST, which makes no sense and won't help you printing form errors. Try using this way;
if edit_profile_form.is_valid():
profile = edit_profile_form.save(commit=False)
profile.save()
else:
print (profile_form.errors)
And check your form for errors.
I figured it out eventually. In the view I should have passed an instance of the profile not the User object. So it needs to be like this:
edit_profile_form = EditProfileForm(request.POST, instance=request.user.*profile*)
I want the users, once they are logged in, to be able to add information about their company including website, name, logo, etc.
I already have this model
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1, unique=True)
comp_name = models.CharField(max_length=120,default='', blank=True)
comp_site = models.URLField(default='', blank=True)
comp_logo = models.ImageField(default='', blank=True, upload_to='img/logos/')
in my views.py I have this:
if form1.is_valid():
saveInfo = form1.save(commit=False)
comp_name = form1.cleaned_data.get("comp_name")
comp_site = form1.cleaned_data.get("comp_site")
comp_logo = form1.cleaned_data.get("comp_logo")
saveInfo.user = form1.user
saveInfo.save()
return redirect('/profil/')
What I'd like is that the program would automatically detects which user is currently logged in, and set the user field to that user.
How could I do this?
The request attribute sent with any Django specifies the current user.
def myview(request):
current_user = request.user
You can check if the user is logged in using the request.user.is_authenticated() method. What I would do here is redirect the login view to the view with your form. This should automatically happen if you are using #login_required on the form view.
As an aside, if you are extending the User model, you should use OneToOneField instead of ForiegnKey. Use ForiegnKeyonly if each user can have multiple companies.
if form1.is_valid():
saveInfo = form1.save(commit=False)
comp_name = form1.cleaned_data.get("comp_name")
comp_site = form1.cleaned_data.get("comp_site")
comp_logo = form1.cleaned_data.get("comp_logo")
saveInfo.user = request.user #<--- the authenticated user bound to the current request
saveInfo.save()
return redirect('/profil/')
request.user is the current user who is bound to the current request. You must (probably you already do) check if user is authenticated etc..
You can associate the users to a model using one to one field as shown below
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
bio = models.TextField()
organisation = models.CharField(max_length=300, default="")
country = models.CharField(max_length=50, default="")
display_pic = models.ImageField(upload_to="authors/profile", default="")
You can then get their info of user using 'Profile' and 'User'