so I've just started studying Django, and ran into a problem.
I'm trying to create a user-specific page, in which if user logs in and inputs his/her info, the info is displayed on the screen, dynamically of course.
So let me show you the codes I wrote.
Here's models.py
class UserInfo(models.Model):
authuser = models.ForeignKey(User, on_delete=models.CASCADE, related_name = 'userinfo', null=True,
default=None)
name = models.CharField(max_length=50)
introduction = models.CharField(max_length=100)
And here's views.py
#login_required(login_url="/register")
def main(response):
thisUser = # I have no idea on which code to write here.
return render(response, 'main.html', {'thisUser' : thisUser})
And here's the html file, main.html
{% extends 'base.html' %}
{% block content %}
{{thisUser.name}}
{{thisUser.introduction}}
{% endblock %}
So this is what I've done so far. I have completed all the registration/login/logouts, as well as the forms for letting users input their info(name, introduction). And the next step I'm trying to take is this user specific page, but I have no idea on how to create it.
I would very much appreciate your help. Thanks. :)
First You user OneToOneField in Your UserInfo model as i give
class UserInfo(models.Model):
authuser = models.OneToOneField(User, on_delete=models.CASCADE, related_name = 'userinfo', null=True,
default=None)
name = models.CharField(max_length=50)
introduction = models.CharField(max_length=100)
Then makemigrations and then migrate
I think you done login/singup with user model
after login what ever page you render that write only the give line
#in you html file
{% extends 'base.html' %}
{% block content %}
Name : {{ request.user.userinfo.name }}
Introduction : {{ request.user.userinfo.introduction }}
{% endblock %}
If you face problem with extends user of onetoone field i give link refer it
User extends for profile or info
Sing up with profile
Login of user
if still you have problem let me know..!
better to change user field to onetoone field
thisUser = UserInfo.objects.get(authuser=request.user)
(also change def main(response) to def main(request)/same in render also)
request.user will give you current login user object
you can do same in template example:
<h1>Name: {{request.user.name}}</h1>
Related
Hello friends I am trying to figure out how to work properly with a One to Many relationship.
I want to create two models,
The first model is Post
And a second model is Comment
Now I say that every post has many comments, and every comment has one post.
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=50)
message = models.TextField(max_length=256,null=True)
def __str__(self):
return str(self.title)
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
message = models.TextField(max_length=256, null=True)
I'm trying to figure out how I can get all the posts and all the comments so that all the comments match the post to which they belong
That is, in the functions in the views file how do I send back this option.
because on the HTML page I want to display the post with all its comments
but there are a number of posts, so how do I do that?
The only thought I can do is this:
dict = {}
all_posts = Post.objects.all()
for post in all_posts:
dict[post] = Comment.objects.filter(post=post).values()
print(dict)
but I have a feeling there is something better
You can access all related comments for a post by using post.comment_set.all() see Following relationships “backward”
{% for post in all_posts %}
{{ post }}
{% for comment in post.comment_set.all %}
{{ comment }}
{% endfor %}
{% endfor %}
To reduce the number of queries use prefetch_related to get all related comments for all posts in a single query
def posts_list(request):
all_posts = Post.objects.prefetch_related('comment_set')
return render(request, 'template.html', {'all_posts': all_posts})
I try to build a blog and this blog in the home view www.site.com consist of posts and these posts have comments, Now I Show the posts using List [] because the user has the ability to follow the content and in this list, I show the content based on the user, Now I successfully to show the posts but this post contains comments that's mean I need to get the pk of the post but as I said this post in the home view www.site.com without any extra URL that's mean as My knowledge I can't pass the pk in the def home_screen_view(request, pk) because this raise error home_screen_view() missing 1 required keyword-only argument: 'pk'
So my qustion how can I get the pk in the base url www.site.com
My view
def home_screen_view(request, *args, **kwargs):
users = [user for user in profile.following.all()]
post = []
for u in users:
p = Account.objects.get(username=u)
posts = p.post_set.all()
post.append(posts)
my_posts = request.user.post_set.all()
post.append(my_posts)
if len(post):
post= sorted(chain(*post), reverse=True, key=lambda post: post.created_date)
posts = Post.objects.filter(pk=post.pk) # here I want to get the pk of the post in order to show the comments related this post
comment = PostCommentIDE.objects.filter(post=posts)
The url
path('', home_screen_view, name='home'),
My Post Model
class Post(models.Model):
author = models.ForeignKey(Account, on_delete=models.CASCADE)
article = models.TextField(null=True, blank=True)
photo_article = models.ImageField(max_length=255, upload_to=get_poster_filepath)
created_date = models.DateTimeField(auto_now_add=True)
My Comment Model
class PostCommentIDE(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='ide_com')
author = models.ForeignKey(Account, on_delete=models.CASCADE)
content = models.TextField()
created_date = models.DateTimeField(auto_now_add=True)
The post template
{% for post in posts %}
...
#here I want to render the comments that related to spesific post
{% for comment in comments %}
{{ comments.content }}
{% endfor %}
...
{% endfor %}
I use function based view
From your home_screen_view you can remove
comment = PostCommentIDE.objects.filter(post=posts)
Instead, in your template you can do:
{% for comment in post.ide_com.all %}
{{ comments.content }}
{% endfor %}
Explanation:
Your comment model PostCommentIDE has a ForeignKey relationship with Post. This enables you to get the related comments for a post. By default you could have accessed the comments with post.postcommentide_set.all, but as you've defined a related_name attribute on that relationship, it becomes post.ide_com.all. Read more about it here: https://docs.djangoproject.com/en/3.2/ref/templates/language/#accessing-method-calls
This is my class models.py I have tried the .split method but keep getting an error that Charfield can not iteriet. I'm trying to make it so that when I call posts in a template if there is a username starting with # it will have the username link to that users profile.
class Status1(models.Model):
post = models.CharField(max_length=333)
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateTimeField(auto_now=True)
You use the below statement for your purpose:
{% if val|slice:":1" == '#' %}
#Doing stuff
{% endif %}
I don't understand what could be the problem of this kind of error. I have 4 apps in my Django project. Each app contains multiple models. I am able to retrieve data from all models expect 1 in the python interactive shell.
Also, in my Form, it gets displayed but when i run the same query from the interactive shell it does not display anything.
I fail to understand what could be the problem, it does not gives any errors as well...
Any help on this would be great!
Updated:
The model contains the following fields:
class Report(models.Model):
rid = models.CharField(blank=True, null=True)
period = models.CharFiedl(blank=True, null=True)
name = models.CharField(blank=True, null=True)
....
....
I was running the following queries:
Report.objects.all() - which returns null
Report.objects.count() - which also return 0
I added a few entries with the help of the admin interface...and checked the same via phpMyadmin...and the interactive shell does not display anything...
But I have a form which is working when i display just the name...
forms.py
class ReportForm(forms.ModelForm):
class Meta:
model = Report
views.py
def display(request):
return render_to_response('view.html', {'Report' : Report.objects.all()})
view.html
{% if Report.count > 0 %}
{% for entries in Report %}
{{entries.name}}
{% endfor %}
{% else %}
<p> No Entries </p>
{% endif %}
I have the following models:
class Post(models.Model):
message = models.TextField()
(etc.)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
(etc.)
class PostFollow(models.Model):
post = models.ForeignKey(Post, related_name='follower_set')
follower = models.ForeignKey(UserProfile, related_name='follower_set')
creation_date = models.DateTimeField(auto_now_add=True)
an_arbitrary_score = models.IntegerField(default=0)
(etc.)
class Meta:
unique_together = ('post', 'follower',)
In my template, I'd like to render a list of posts along with a "follow" or "unfollow" link so that the current user can decide whether to follow a given post. In a world where I could use arguments in Django templating, I'd do something like this:
{% for post in post_set %}
<...stuff...>
{% if post.user_is_following user %}unfollow{% else %}follow{% endif %}
<...more stuff...>
{% endfor %}
However, I can't do that. And I can't make a zero-argument, template-callable method on any of these models, because they all need to know at least one other argument to answer the question whether a given PostFollow row exists in that table.
I'm happy to write a templating extension, but before I bring out the big guns, is this an appropriate case for doing so? Or is there a more Djangoesque solution?
Template filters are not big guns:
# your_app/templatetags/following.py
from django import template
register = template.Library()
#register.filter
def is_followed_by(post, user):
return post.is_followed_by(user)
and then:
{% load following %}
...
{% if post|is_followed_by:user %} ... {% endif %}
You can also put all logic in template filter, remove 'post.is_followed_by' method and use the filter instead of model method just like any other function, #register.filter decorator doesn't harm the decorated function.