I would like to implement a functionality where another user A clicks the picture of a different user B and is automatically redirected to the profile of user B. how do I do this? please look at my HTML where I stated something about a link
view.py
class profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
bio = models.TextField(blank=True)
def __str__(self):
return f'{self.user.username} profile'
html:
{% for post in posts %}
<div class="icl-NavigationList-item">
<div class="icl-NavigationList-link icl-NavigationList--primary">
<div class="icl-NavigationList-text">
<h2 class="icl-NavigationList-title">
<div class="upperText">
<h2 class="card-title"style="background-color:{{post.post_colours}};">{{post.job_title}}</h2>
<a class="a-tags" href="*{{ i need to link the post author's profile here}}*" data-tippy-content="#dribble_handle">
<img src="{{post.author.profile.profile_pic.url}}" style="border-radius: 100%;float:right;"
alt="author"width="30" height="30"></a></div>
<div class="lowerText"> <p class="card-text">{{post.currency}} {{post.salary}}</p>
<p class="card-text"> Posted on {{post.date_posted}} by {{post.author}} </p>
<br>
{% if user.is_authenticated %}
my model
class profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
bio = models.TextField(blank=True)
category = models.CharField(max_length= 1000, choices =
Select_category,default='other')
def get(self, request, *args, **kwargs):
username = self.kwargs['username']
user_profile = profile.objects.get(user__username=username)
gigs = Gig.objects.filter(user__username=username, status=True)
print(user_profile.values())
return render(request, 'blog/profile.html', {'user_profile': user_profile, 'gigs': gigs,'name': username})
Alright, here’s an edited answer. I took a look at your code, and you don’t have the post model on here, so this is just me trying to put some pieces together to try. Ultimately, our goal should be to have the href look like this:
href="{{ post.author.get_absolute_url }}"
Note here that it is NOT {{ post.author.profile.get_absolute_url }}. It probably seems counter-intuitive to leave out profile in the url, but remember that the username argument passed is part of the User model, not the profile model.
(Note: the url will definitely depend on what the model for your post looks like. If the author is a ForeignKey to the user model, use what I’m typing here. If it is a ForeignKey relating to the profile model, you would replace author with author.user)
If that doesn’t work, make sure your urls.py is set up correctly.
urls.py
...
path(‘URL_YOU_WANT/<username>/, views.VIEW_NAME, name=“NAME”),
...
(Note: keep “<username>” exactly like that. It’s how Django knows to expect the username argument passed by your href.)
If things still aren’t working, I would rewrite your views.py view to be clearer. There is a bit of redundancy and confusion with your views.py and models.py. Here’s how I would go about it:
models.py
class profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
bio = models.TextField(blank = True)
def __str__(self):
return f’{self.user.username} profile’
views.py
def user_profile(request, username):
user = User.objects.get(username = username)
user_profile = profile.objects.get(user = user)
gigs = Gig.objects.filter(user = user, status = True)
return render(request, ‘blog/profile.html’, {‘user_profile’: user_profile, ‘gigs’: gigs, ‘name’: username})
Let me know if this helps!
Related
Django Querying: How do i query an account page through a blog post that the account owner has created? aka link from one to another. So I have an account model and a blog post model, with the author as the foreign key. I am unsure of how i can do the querying of the account. Can anyone advise how this is normally done? Because I tried to do user_id=request.user.id but this would take me to my own account view. Thanks!
html
<a class="dropdown-item" href="{% url 'account:view' %}">{{blog_post.author}}</a>
views.py
def detail_blog_view(request, slug):
context = {}
blog_post = get_object_or_404(BlogPost, slug=slug)
context['blog_post'] = blog_post
return render(request, 'HomeFeed/detail_blog.html', context)
urls.py for Blogs
path('<slug>/detail/', detail_blog_view, name= "detail"),
urls.py for accounts:
path('<user_id>/', account_view, name="view"),
models.py
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
class BlogPost(models.Model):
title = models.CharField(max_length=50, null=False, blank=False)
body = models.TextField(max_length=5000, null=False, blank=False)
slug = models.SlugField(blank=True, unique=True)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
You don't really need to query the author, what you do is just get the foreign key value from the BlogPost object like this:
views.py
def post(request, pk):
post = BlogPost.objects.get(pk=pk)
author = post.author
return render(request, 'post.html', {'post': post,
'author': author})
Then display it in a template:
post.html
{{ author }}
(or you can use {{ post.author }} here aswell) says:
{{ post.title }} | {{ post.body }}
EDIT
in your urls where you have a path to your user profile you actually need to specify the argument type like:
path('<int:user_id>/', account_view, name="view"), # btw dont call your views 'view', name should describe what the view actually does or shows
I am new to django but really want to learn how to use this framework.
What want to do :
I have a form, that allows the user to create a new client for example.
So in this form I have 3 fields :
Name
Description
Skills
The 'Skills' field is currently a text area, where the user would copy and paste a list already existing in another document(excel). Therefore, each element is separated by a splitline.
What I would like to do is :
create in the database the client entered by the user
In the database, link the description entered by the user to the client
In the database, link each skill entered by the user to the name so that I can work on them independantly of each other in further functions/apps. I don't want all of the skills to be linked to the client as one big bloc.
So I read the documentation and thought about using a ForeignKey. The thing is I was unable to get an input text area when using a ForeignKey. Everytime I used it I got an empty 'select list' like this ...
Empty list field
And even though I would be able to get that, I still don't know how to treat each element separatly of the others..
This is the code I have now :
model.py
class Post(models.Model):
name = models.CharField(max_length=100, null=True)
description = models.TextField(null=True)
skills = models.TextField(null=True)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
views.py
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['name', 'description', 'skills']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
post_form.html
{% extends "taskflow/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Client</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Save</button>
</div>
</form>
</div>
{% endblock content %}
As an example of what I tried to implement using a Foreign Key :
models.py
class Skills(models.Model):
element = models.TextField(null=True)
class Post(models.Model):
name = models.CharField(max_length=100, null=True)
description = models.TextField(null=True)
skills = models.ForeignKey(Skills, on_delete=models.CASCADE)
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
views.py
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['name', 'description', 'skills']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
If in views.py, instead of calling 'skills' I call 'element', I get an error saying 'element' is undefined.
I thought that using a ForeignKey would include the 'element' field contained in Skills in the 'skills' field contained in Post. So from what I understand it is not the case.
What am I doing wrong?
Any information and tips would be welcome.
Thanks a lot.
Displaying foreign key field
If you want to display skills.element in your view then you don't have to call skills.element in fields just define __str__() method in your Skills model.
class Skills(models.Model):
element = models.TextField(null=True)
def __str__(self):
return self.element
p.s. Regarding the relation between Post and Skill, I think it might be Many to Many because one Post can have many Skills and one Skill can belong to many Posts but your current model doesn't allow that (Any Post can have only one Skill while one Skill belong to many Post).
You can find out more about how to implement many to many relationship in Django at https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_many/
** I CHANGED SKILLS TO ADDRESS **
I thought about this :
Get a TextField instead of ForeignKey
the user enters his list like this for example :
TextField
Then in Views.py I try to parse it, by creating a new field and use splitlines() like this:
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['name', 'description', 'address']
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.address_list = self.object.address.splitlines()
form.instance.author = self.request.user
self.object.save()
return super().form_valid(form)
Here I think i need to do something like
for element in self.object.address_list:
#create object here
But I don't really know how to do it and most of the time I get
Post object has no attribute object
And also, in my template if I use for example :
<p class="article-content">{{ post.address_list }}</p>
I get ['123456', '123457', '123458']
And if I use :
{{ post.address_list.1 }}
I'll get the first str character which is '
So the general idea would be to get from this form this output in the db :
db
as I want to create an instance of each address in the db, linked to the client.
Thanks for your very appreciated help !
Django user profile model form data is not getting displayed on the template, not even giving me an error!
I am learning to create Django registration form with user profile models I have created the registration form and profile form successfully but I am not getting any values from models.py file.
Models.py
class ExtenduserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
birth_date = models.DateField(null=True, blank=True)
age = models.IntegerField()
def __str__(self):
return self.user.username
#receiver(post_save,sender=User)
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile =
ExtenduserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
forms.py
class userprofile(forms.ModelForm):
birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD')
class Meta:
model = ExtenduserProfile
fields = ('age','birth_date')
views.py
#login_required()
def UserProfile(request,pk=None):
profile = ExtenduserProfile.objects.all()
return render(request,'dashboard/profile.html',{'profile':profile})
#login_required()
def HomeScreen(request):
if request.user.is_authenticated:
username = request.user.username
else :
username = 'not logged in'
context = {'username':username,'user':user}
return render(request,'dashboard/Home.html',context)
def singup(request):
if request.method == 'POST':
form = SignupForm(request.POST)
user_profile = userprofile(request.POST)
if form.is_valid() and user_profile.is_valid():
user = form.save()
profile = user_profile.save(commit=False)
profile.user = user
profile.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username = username, password = password)
login(request,user)
return redirect(login_view)
else:
form = SignupForm()
user_profile = userprofile()
context = {'form':form, 'user_profile':user_profile }
return render(request,'account/signup.html',context)
HTML file
{% extends 'dashboard/base.html' %}
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Profile</title>
</head>
{% block content%}
<body>
<h3>Welcome to profile page</h3><br>
{% if user.is_authenticated %}
<h4>Name = {{user.first_name}} {{user.last_name}}</h4>
<h4>Email = {{user.email}}</h4>
<h4>Age = {{user.ExtenduserProfile.age}} </h4>
<h4>DOB = {{user.ExtenduserProfile.birth_date}} </h4>
{% endif %}
</body>
{% endblock%}
</html>
my expected output should be
name: xyz
email: abc#abc.com
age: 24
DOB: 1994-04-21
What is a Custom User Model Extending AbstractUser?
It is a new User model that inherit from AbstractUser. It requires a special care and to update some references through the settings.py. Ideally it should be done in the begining of the project, since it will dramatically impact the database schema. Extra care while implementing it.
When should I use a Custom User Model Extending AbstractUser?
You should use it when you are perfectly happy with how Django handles the authentication process and you wouldn’t change anything on it. Yet, you want to add some extra information directly in the User model, without having to create an extra class.
I suggest to you to use Abstract User
Which is easier and best practice for your case
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
Also add this to your setting :
AUTH_USER_MODEL = 'appname.User'
Check this tutorial for more information
Well, when you are using reverse relation in OneToOne, the class name should be in all lowercase(documentation). For example:
<h4>Age = {{user.extenduserprofile.age}} </h4>
<h4>DOB = {{user.extenduserprofile.birth_date}} </h4>
Also, why are you sending profile = ExtenduserProfile.objects.all() to template via context from your profile view? Because as I can see, you are not using it. So I think you can remove that part of code as well.
Also, you can remove the {% if user.is_authenticated %} and {%endif%} from template. As, this template can't be accessible unless you are logged in. You have restricted that via login_required decorator.
I want to get all posts that a user send. For example user: admin, it will show admin's posts. I write some code, but probably I made a mistake and I got an error.
The error that I get:
AttributeError at /index_page/
'WSGIRequest' object has no attribute 'models'
Here is my code:
views.py
def index_page(request):
logged_in_user = request.models.author
logged_in_user_posts = Post.objects.filter(author=user)
return render(request, 'blog/post_list.html', {'posts': logged_in_user_posts})
models.py
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = RichTextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
post_list.html
<div>
{% for post in posts %}
Username: {{ post.author.username }}
Post: {{ post.text }}
<br>
{% endfor %}
Where is my mistake?
The error already hints to the line:
logged_in_user = request.models.author
A request object has no models attribute. It has a .user attribute that specifies the logged in user, so you can use:
logged_in_user = request.user
There is another error: you use Post.objects.filter(user=user), but there is no user variable either, there is a logged_in_user variable. So you can fix the view with:
def index_page(request):
logged_in_user_posts = Post.objects.filter(author=request.user)
return render(request, 'blog/post_list.html', {'posts': logged_in_user_posts})
Extra notes:
since you need a user, it makes sense to decorate the function with the login_required decorator [Django-doc]; and
Since Django allows you to change the User model, it might be beneficial to use the standard way to refer to the user model [Django-doc]. If you later change your mind and implement another user model, the creating migrations will automatically let the relations refer to the new model.
The two comments above are not strictly necessary to let it work. But it is what I think are good practices when developing Django apps (although of course these can be a bit "opinion-based").
The issue is in your view, request object does not contain your models.The view should be like below,
def index_page(request):
logged_in_user = request.user
logged_in_user_posts = Post.objects.filter(author=logged_in_user)
return render(request, 'blog/post_list.html', {'posts': logged_in_user_posts})
I am answering a little bit late , But may be it help someone later . you can use class-based views . In your case
views.py :
class UserPostListView(ListView):
model = Post
template_name = 'app_name/template_name.html'
context_object_name = 'posts'
def get_queryset(self):
user = get_object_or_404(User,username=self.kwargs.get('username'))
return Post.objects.filter(author=user)
and in your urls.py :
path('user/<str:username>', views.UserPostListView.as_view(), name='user-posts'),
and then in your template :
{% block content%}
<h1> My files </h1>
{% for post in posts %}
{% endfor %}
{% endblock %}
I have the following model in my Django project:
from django.contrib.auth.models import User
class Project(models.Model):
project_title = models.CharField(max_length=200)
project_description = models.CharField(max_length=200, default="")
created_date = models.DateTimeField('date created')
owner = models.ForeignKey(User)
def __str__(self):
return self.project_title
This view uses the Project model as follows:
class ProjectView(generic.edit.UpdateView):
model = Project
fields = ['project_title','project_description']
template_name = 'steps/project.html'
success_url = reverse_lazy('steps:index')
My question is how can I bring the User's fields into my ProjectView so I can then use them in templates? In particular, I would like to display the logged-in user's name and email.
user information placed on request, not on views. So you can write in template {{user.username}}, or {{user.email}}. and you'll get it. Of course if user.is_authenticated
in your template write:
{% if request.user.is_authenticated %}
{{ request.user.username }}
{{ request.user.email }}
{% endif %}