I have a Django project that allows users to create their own Projects and add multiple Skills to each Project.
I am trying to write a view that will allow me to display the name of each Skill as well as the Count of that Skill for all of that particular user Profile's Projects that are published.
For example, if a user has three projects where they've added the Skill "HTML" I'd like to show HTML (3) on their Profile, and so on.
Below is my current code which mostly works however it displays the count for that Skill from ALL user projects and not the specific user whose profile is being viewed.
Models:
#accounts/models.py
class Profile(models.Model):
#...
skills = models.ManyToManyField('skills.skill')
#projects/models.py
class Project(models.Model):
user = models.ForeignKey(User)
#...
published = models.BooleanField(default=False)
skills = models.ManyToManyField('skills.skill')
#...
#skills/models.py
class Skill(models.Model):
name = models.CharField(max_length=100)
Views:
#accounts/views.py
def profile(request, username):
user = get_object_or_404(User, username=username)
skill_counts = Skill.objects.annotate(num_projects=Count('project')).filter(project__user_id=user.id).order_by('-num_projects')[:10]
return render(request, 'accounts/profile.html', {
'user': user,
'skill_counts': skill_counts,
})
Template:
#accounts/templates/accounts/profile.html
{% for skill in skill_counts %}
<div class="skill-container">
<div class="label-skill">{{ skill.name }}</div> <div class="label-skill-count">
{{skill.project_set.count}}</div>
</div>
{% endfor %}
Any help here would be much appreciated.
Thanks in advance.
Note that I'm voting to close this as this question has been answered here.
Basically you need to use django's conditional expressions Case and When.
Here is a quick example of how this could look:
from django.db.models import Count, Case, When
# ...
Skill.objects.annotate(
num_porjects=Count(Case(
When(project__user_id=user.id, then=1),
output_field=CharField(),
))
)
Related
I am building a website where user come and login, after login user publish articles with admin approval . I do not know how to do it. I made a user authentication system where user can login. But i do not know how to make him post data with admin approval.
Therefor you need a condition in your model to be able to query the approved objects (blog posts) to display.
A basic approach could look as follows:
Create a model to store the blog posts and its logic to the database
# models.py
class Blog_Post(models.Model):
text = models.CharField(max_length=500)
is_approved = models.BooleanField(default=False)
def __str__(self):
return self.name
Register your model in the admin so you can approve them via django-admin
from django.contrib import admin
from myproject.myapp.models import Blog_Post
admin.site.register(Blog_Post)
Create a view to only fetch blog posts that have been approved by an admin
# views.py
def get_blog_post(request):
# Only fetch the blog posts that are approved
queryset = Blog_Post.objects.filter(is_approved=True)
return render(request, 'your_html.html', {'queryset' : queryset})
Render the blog posts in your template
# your_html.html
{% for blog_post in queryset %}
<div>{{ blog_post.text }}</div>
{% endfor %}
That's a Good one. You can enable this with adding a new column to your database like onapproval Set it as an boolean variable like 0 or 1 either true or false. Then check for it. If it's true you can set the status as approved and if it is not set it as not approved. The same process will also takes place in admin panel too.
I am in the process of learning Django. I am trying to create a simple directory web app. I am able to print out all the users details for the main directory page. However, I want to add a feature that when a person logs into the directory app they are brought to their 'profile' page where they will be able to see all their own details e.g. business name, profile pic.
I know how to retrieve the default fields e.g. username and email. But cannot seem to retrieve the custom fields that I declared myself. Here is my attempts so far...
Models.py:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserProfileInfo(models.Model):
user = models.OneToOneField(User,on_delete=models.DO_NOTHING)
#additional classes
business_name = models.CharField(max_length=191,blank=True)
trade = models.CharField(max_length=191,blank=True)
portfolio_site = models.URLField(blank=True)
profile_pic = models.ImageField(upload_to='profile_pics',blank=True)
def __str__(self):
return self.user.username
Views.py:
#login_required
def profile(request):
profile = UserProfileInfo.objects.filter(user=request.user)
context = { 'profile': profile }
return render(request, 'dir_app/profile.html',context)
Profile.html:
<div class="container-fluid text-center">
{% for p in profile %}
<h3>{{p.business_name}}</h3>
{% endfor %}
</div>
Since UserProfileInfo is related to User via OneToOneField, you can have one UserProfileInfo per User. So, instead of Filter, you can simply get your desired UserProfileInfo object through your current (logged in) User as follows.
views.py,
profile = UserProfileInfo.objects.get(user=request.user)
Also, before you can get a request.user object, you have to make sure that your user is authenticated and logged in. Otherwise, you might get None in place of a User object and therefore, no associated UserProfileInfo.
Since it is a OneToOneField there is only one Profile object for a User, you thus can obtain this with:
#login_required
def profile(request):
profile = request.user.userprofileinfo
return render(request, 'my_template.html',{'profile': profile})
Then in the template, you render it with:
{{ profile.business_name }}
you can use it directly on template without sending it f:
{{request.user.userprofile}}
I'm developing to-list app with registration . I have two models : Model for User and Model for Tasks . I add new task throw Ajax to one user it adding and displaying for every user. Is there any solutions ? Here some pictures
Here is my code:
models.py
class Task(models.Model):
title=models.IntegerField()
date = models.DateTimeField(default=datetime.now,blank=True)
is_published=models.BooleanField(default=True)
class CustomUser(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
image=models.FileField(upload_to='photos/%Y/%m/%d/',null=True,blank=True)
views.py
if request.method == 'POST' and request.POST['form_type'] == 'task':
if request.is_ajax():
addtask = AddTask(request.POST)
if addtask.is_valid():
user = request.user.id
addtask.objects.filter(user=user).cleaned_data
addtask.objects.filter(user=user).save()
task_object = Task.objects.filter(user=user)(addtask)
return JsonResponse({'error': False, 'data': task_object})
else:
print(addtask.errors)
return JsonResponse({'error': True, 'data': addtask.errors})
else:
error = {
'message': 'Error, must be an Ajax call.'
}
return JsonResponse(error, content_type="application/json")
addtask = AddTask()
task = Task.objects.order_by('-date').filter(is_published=True)
html page
{% if task %}
{% for tas in task %}
Task content
{% endfor %}
{% else %}
{% endif %}
Maybe you should add relation to CustomUser in Task model and filter tasks by owner in view before to render data to template?
class Task(models.Model):
title=models.IntegerField()
date = models.DateTimeField(default=datetime.now,blank=True)
is_published=models.BooleanField(default=True)
user=models.ForeignKey(CustomUser)
class CustomUser(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
image=models.FileField(upload_to='photos/%Y/%m/%d/',null=True,blank=True)
And in view:
...
addtask = AddTask()
task = Task.objects.filter(is_published=True, user_id=request.user.id).order_by('-date')
So the mistake is that you never connected your CustomUser model with your Task model. They should have a relationship like one to many. Once that is achieved, you have to retrieve only the tasks related to the user of interest from the database and send them to the HTML page. Then only the tasks related to one particular user will be displayed.
If you want to create CustomUser model, you should create a class and inherit it from AbstractBaseUser or AbstractUser(django documentation).
Your Task model hasn't relationships with CustomUser. You create AddTask(?) instance but didn't bind it with any user.
You did not submit a view which renders HTML template, but I think that your query is something like Tasks = Task.objects.all() which return all tasks.
This is how you should create CustomUser model
This is documentation about relationships in Django
This is about making queries in Django
I have a problem. I have given some random numbers in admin page as a balance for users and connected it to database. Basically I want it to show for different users different payments. But I don't know what to write in views.py and html page so that it shows different payment for different users.
models.py
class Payment(models.Model):
payment_numbers = models.CharField(max_length=100)
views.py
def payment(request):
receiving1 = Payment.objects.all()
for field in receiving1:
field.payment_numbers
context = {
'receiving1': receiving1
}
return render(request, 'index.html', context)
HTML PAGE
{% for numbers1 in receiving1 %}
<li style="float: right;">Your Balance: Rs. {{numbers1.payment_numbers}}</li>
{% endfor %}
You need to modify your models so that payments have a relationship with your users.
A simple way to do that is a ForeignKey to your user model.
class Payment(models.Model):
payment_numbers = models.CharField(max_length=100)
owner = models.ForeignKey('yourusermodel')
Once this is done, you can update your views to pass only the right payments to the context.
receiving1 = Payment.objects.filter(owner=request.user)
This will of course require you to create new migrations and to ensure your users are properly logged in. Most of this is explained in the Django Tutorial
Good Morning All,
I've been a PHP programmer for quite some time, but I've felt the need to move more towards the Python direction and what's better than playing around with Django.
While in the process, I'm come to a stopping point where I know there is an easy solution, but I'm just missing it - How do I display manytomany relationships in a Django Template?
My Django Model: (most of the fields have been removed)
class Category(models.Model):
name = models.CharField(max_length=125)
slug = models.SlugField()
categories = models.ManyToManyField(Category, blank=True, null=True)
class Recipe(models.Model):
title = models.CharField('Title', max_length=250)
slug = models.SlugField()
class Photo(models.Model):
recipe = models.ForeignKey(Recipe)
image = models.ImageField(upload_to="images/recipes", blank=True)
So, there is the basic models I'm using in my application called "recipes."
With that said, there are two questions I'm looking for answers on:
How would I go about displaying the categories for a recipe on it's details page?
How would I go about displaying the image for the recipe on it's details page?
If I go into the Python shell, and input the following, I do get a result:
>>> photos = Photo.objects.filter(recipe=1)
>>> photos
[<Photo: Awesome Pasta>]
>>> for photo in photos:
... print "Photo: %s" % photo.logo
...
Photo: images/recipes/2550298482_46729d51af__.jpg
But when I try something like the following in my template, I get an error saying "Invalid block tag: 'photo.image'."
{% for photo in photos %}
{% photo.image %}
{% endfor %}
Although, even if that did work, the ID is still hard coded into the view, how would you go about having this dynamic for each recipe?
Details Page View.py snippet:
def details(request, slug='0'):
p = get_object_or_404(Recipe, slug=slug)
photos = Photo.objects.filter(recipe=1)
return render_to_response('recipes/recipes_detail.html', {'p': p, 'photos': photos})
Thanks in advance for the help and understanding for what is probably a very simple question to all of you!
UPDATE: When removing the additional fields in the models, I forgot the categories field for the Recipes model.
From what I can see, I think you've got a small syntax error:
{% photo.image %}
should instead be:
{{ photo.image }}
The {% %} notation is used for django template tags. Variables, on the other hand, are expressed with the {{ }} notation.
To make it dynamic, you can take advantage of the fact that your Photo model has a foreign key to Recipe. This means that there will be a reverse relation from the Recipe instance you've loaded using the slug back to the set of photos:
def details(request, slug='0'):
p = get_object_or_404(Recipe, slug=slug)
photos = p.photo_set.all()
Hopefully that will work for you. Glad to see you're enjoying working with Django!