I have 2 models: UserProfile and User_Details and I want to display the details for one user.I think the problem is at the filter and I don't know how to filter after a string,I'm new to django.How can I fix this?
class ShowProfile(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'profile.html'
def get(self, request, pk, format=None):
details=User_Details.objects.all().filter(user=request.user.username)
serializer = ProfileSerializer2(details, many=True)
pprint.pprint(json.loads(JSONRenderer().render(serializer.data)))
return Response({'fields ': serializer})
def post(self, request):
serializer = CreatePostSerializer(data=request.data)
if not serializer.is_valid():
return Response({'fields': serializer })
user = UserProfile.objects.filter(username=request.user.username).first()
serializer.save(user=user)
pprint.pprint(json.loads(JSONRenderer().render(serializer.data)))
return redirect('mainPage')
Models:
class UserProfile(AbstractUser):
pass
class User_Details(models.Model):
user = models.OneToOneField(UserProfile, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50, blank = True)
last_name = models.CharField(max_length=50, blank=True)
gender = models.CharField(max_length=6, blank=True, default='')
public_info=models.CharField(max_length=100, blank=True, default='')
Template:
{% extends 'base2.html' %}
{% load rest_framework %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-3 ">
<div class="list-group ">
Profile
My Posts
</div>
</div>
{% for d in fields %}
{{d.firs_name }}<h1>a</h1>
{% endfor %}
{% endblock %}
Related
I'm working on a blog and I was following instructions but now I don't understand why I have problem with pk.
This is my views.py
from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import Category, Post
def post_list(request):
posts = Post.objects.filter(created_at__lte=timezone.now()).order_by('created_at')
latest_posts = Post.objects.filter(created_at__lte=timezone.now()).order_by('created_at')[:9]
context = {'posts': posts, 'latest_posts': latest_posts}
return render(request, 'home.html', context)
def post_detail(request, post, pk):
latest_posts = Post.objects.filter(created_at__lte=timezone.now()).order_by('created_at')[:9]
post = get_object_or_404(Post, pk=pk)
context = {'post': post, 'latest_posts': latest_posts}
return render(request, 'post_detail.html', context)
This is blog/urls.py
urlpatterns = [
path('', views.post_list, name='home'),
path('<slug:post>/', views.post_detail, name='post_detail'),
]
This is models.py
class Post(models.Model):
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
is_published = models.BooleanField(default=False, verbose_name="Is published?")
published_at = models.DateTimeField(null=True, blank=True, editable=False, verbose_name="Published at")
title = models.CharField(max_length=200, verbose_name="Title")
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey('auth.User', verbose_name="Author", on_delete=models.CASCADE)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE)
body = RichTextField(blank=True, null=True)
image = StdImageField(upload_to='featured_image/%Y/%m/%d/', variations={'standard':(1170,820),'banner':(1170,530),'thumbnail':(500,500)})
status = models.IntegerField(choices=STATUS, default=0)
def get_absolute_url(self):
return reverse('post_detail', args=[self.slug])
class Meta:
verbose_name = "Post"
verbose_name_plural = "Posts"
ordering = ['-created_at']
def publish(self):
self.is_published = True
self.published_at = timezone.now()
self.save()
def __str__(self):
return self.title
Also, I'm adding a list of post, it might be connected with get_absolute_url
{% extends "base.html" %}
{% load static %}
{% block content %}
<!-- Main Wrap Start -->
<main class="position-relative">
<div class="post-carausel-1-items mb-50">
{% for post in latest_posts %}
<div class="col">
<div class="slider-single bg-white p-10 border-radius-15">
<div class="img-hover-scale border-radius-10">
<!--<span class="top-right-icon bg-dark"><i class="mdi mdi-flash-on"></i></span>-->
<a href="{{ post.get_absolute_url }}">
<img class="border-radius-10" src="{{ post.image.standard.url }}" alt="post-slider">
</a>
</div>
<h6 class="post-title pr-5 pl-5 mb-10 mt-15 text-limit-2-row">
{{ post.title }}
</h6>
<div class="entry-meta meta-1 font-x-small color-grey float-left text-uppercase pl-5 pb-15">
<span class="post-by">By {{ post.author }}</span>
<span class="post-on">{{ post.created_at}}</span>
</div>
</div>
</div>
{% endfor %}
</div>
</main>
{% endblock content%}
I have an error...
post_detail() missing 1 required positional argument: 'pk'
Everything was working until I was started working on post detail. Any ideas why this is happening?
You seem to be confused with what the primary key for your model is. The primary key is the auto-generated id (pk) but according to your urls.py you want to use slug for fetching records.
First, change your path to:
path('<slug:slug>/', views.post_detail, name='post_detail'),
then your view signature to:
def post_detail(request, slug):
and finally, fetch your record using:
post = get_object_or_404(Post, slug=slug)
I m trying to make a comment system on a blog website with using the slug instead of pk
im running into not NULL constraint failed: home_comment.post_id error
my error is coming in the form_valid function in the class based view
form.instance.post_id = self.kwargs['pk']
how do i do this ^ with the slug
form.instance.post__slug = self.kwargs['slug'] (this is showing an error)
views.py
class AddCommentView(CreateView):
model = Comment
form_class = AddCommentForm
template_name = "add_comment.html"
def form_valid(self, form):
form.instance.post__slug = self.kwargs["slug"]
form.instance.name = self.request.user
return super().form_valid(form)
models.py
class Post(models.Model):
title = models.CharField(max_length=1000, default="Title")
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.CharField(max_length=1000, default="Category")
body = models.TextField(default="This is the Body of the Post.")
slug = models.SlugField(max_length=1000, null=True, blank=True)
created_time = models.DateTimeField(auto_now_add=True)
created_date = models.DateField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
updated_date = models.DateField(auto_now=True)
likes = models.ManyToManyField(User, related_name="blog_posts_likes")
dislikes = models.ManyToManyField(User, related_name="blog_posts_dislikes")
class Meta:
verbose_name_plural = "Blogs & Posts"
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = generate_slug(self.title)
super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
return f"/blogs/post/{self.slug}"
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments")
name = models.ForeignKey(User, on_delete=models.CASCADE)
body = models.TextField()
date_added = models.DateField(auto_now_add=True)
time_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = "Post Comments"
def __str__(self):
return "%s - %s" % (self.post.title, self.name.username)
def get_absolute_url(self):
return f"/blogs/post/{self.post.slug}"
html file
{% extends "base.html" %}
{% block content %}
{% if user.is_authenticated %}
<section class="text-gray-600 body-font relative">
<div class="container px-5 py-24 mx-auto">
<div class="flex flex-col text-center w-full mb-12">
<h1 class="sm:text-3xl text-2xl font-medium title-font mb-4 text-gray-900">Add A Comment</h1>
</div>
<div class="mx-auto">
<form method="post">
{% csrf_token %}
{{form}}
<div class="p-2 w-full">
<button
class="flex mx-auto text-white bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">Add</button>
</div>
<div class="p-2 w-full pt-8 mt-8 border-t border-gray-200 text-center">
</div>
</form>
</div>
</div>
</section>
{% endif %}
{% endblock %}
try this
def form_valid(self, form):
form.instance.post = Post.objects.get(slug=self.kwargs["slug"])
form.instance.name = self.request.user
return super().form_valid(form)
I'm trying to build a structure using Django Rest Framework to show some data in my html templates. But I can't show data from a model with ForeignKey.
My structure should be like this:
{% for category in categories %}
{{ category.category }} #category is the variable name
{% for channel in category.channel_set.all %}
{{ channel.title }}
{{ endfor }}
{{ endfor }}
But I can't print the channel variables in html files.
models.py:
class Category(models.Model):
user = models.ForeignKey(
'auth.User',
on_delete=models.DO_NOTHING,
unique=False,
)
category = models.CharField(
max_length=255,
unique=True,
)
_id = models.ObjectIdField(auto_created=True, serialize=False)
event_creation = models.DateTimeField(auto_now=True)
event_updated = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'category'
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.category
class Channel(models.Model):
user = models.ForeignKey(
'auth.User',
on_delete=models.DO_NOTHING,
)
_id = models.ObjectIdField(auto_created=True, serialize=False)
date_creation = models.DateTimeField(auto_now=True)
date_updated = models.DateTimeField(auto_now=True)
category = models.ForeignKey(
Category,
max_length=255,
on_delete=models.PROTECT,
related_name='channel',
unique=False,
to_field='category',
)
channel = models.CharField(
max_length=255,
unique=True,
)
def __str__(self):
return self.category
views.py:
class Gallery(viewsets.ModelViewSet):
renderer_classes = [TemplateHTMLRenderer]
template_name = '/gallery.html'
queryset = Category.objects.all()
queryset2 = Channel.objects.all()
permission_classes = [permissions.IsAuthenticated]
def get(self, request, **kwargs):
kwargs['categories_list'] = self.queryset
serializer = CategorySerializer(self.queryset,many=True)
serializer2 = ChannelSerializer(self.queryset2,many=True)
return Response({
'categories':serializer.data,
'channels':serializer2.data
})
# #login_required(login_url='/login/')
def list(self, request):
queryset = Category.objects.all()
response = {'categories': queryset}
return Response({'categories':queryset})
serializers.py:
class CategorySerializer(serializers.ModelSerializer):
# _id = serializers.ReadOnlyField()
categories = Category()
class Meta:
model = Category
fields = '__all__'
class ChannelSerializer(serializers.ModelSerializer):
# _id = serializers.ReadOnlyField()
channels = Channel()
class Meta:
model = Channel
fields = '__all__'
gallery.html:
{% extends "/model-page.html" %}
{% load core_tags %}
{% block content %}
<h1> co. </h1>
<h2> Last Archives </h2>
<a href="/category-api/">
<button type="button"> New input </button>
</a>
<ul>
{% for category in categories %}
<td> {% underscoreTag category "_id" as category_id %} </td>
<div {% if category.get_pass_event %} style="color: red "{% endif %}>
<li>{{ category.category }} - {{ category.get_creation }}
<ul>
<li>{{ category }}</li>
<ul>
<div>
{% for channel in category.channel_set.all %}
<li>Teste {{ channel.title }}</li>
{% endfor %}
</div>
</ul>
</ul>
Edit /
Delete
</li>
</div>
{% endfor %}
</ul>
{% endblock %}
I had trying for {% for channel in category.channel_set.all %},{% for channel in category.channels_set.all %}, {% for channel in category.channel.all %} and {% for channel in category.channels.all %} and any of these worked for me.
Another info from my project is that I'm using Django (because my database is MongoDB).
I think the code of the serializers isn't correct.
class ChannelSerializer(serializers.ModelSerializer):
class Meta:
model = Channel
fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
channel = ChannelSerializer(many = True, read_only = True)
class Meta:
model = Category
fields = '__all__'
And in the html, some attributes don't exist in the models. channel_set should be changed into channel and channel.title into channel.channel.
There are no names like channel_set, title in the models.
...
<ul>
<div>
{% for channel in category.channel %}
<li>Teste {{ channel.channel }}</li>
{% endfor %}
</div>
</ul>
...
Or you should modify the names in the models.
how can I retrieve the lesson modules by its parent lesson strictly? e.g if I change to the next lesson where at the same contains a lessonmodule /lesson1/task1 this one shouldn't display since it doesn't belong to lesson2? how can I fix this by only retrieve slugs, content by the lesson attach to?
views
class LessonDetailView(LoginRequiredMixin, View):
login_url = "/account/login/"
def get(self, request, course_slug, lesson_slug, *args, **kwargs):
lesson = get_object_or_404(Lesson.objects.select_related('course'), slug=lesson_slug, course__slug=course_slug)
lessonmodule = get_object_or_404(LessonModule.objects.select_related('lesson'), slug='hello_world')
context = {
'object': lessonmodule,
'previous_lesson': lesson.get_previous_by_created_at,
'next_lesson': lesson.get_next_by_created_at,
}
return render(request, "courses/lesson_detail.html", context)
models
class Lesson(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(max_length=25,unique=True)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('lesson-detail',
kwargs={
'course_slug': self.course.slug,
'lesson_slug': self.slug
})
class LessonModule(models.Model):
slug = models.SlugField(unique=True, blank=True, null=True)
content = models.TextField()
lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE)
allowed_memberships = models.ManyToManyField(Membership)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
updated_at = models.DateTimeField(auto_now=True, blank=True)
def __str__(self):
return self.slug
template
{% block content %}
<div class='container'>
<h1>Lesson Detail View</h1>
<div class='row'>
<div class='col-sm-6 col-md-6'>
{% if object is not None %}
<h3>{{ object.title }}</h3>
<p>{{ object.course.description }}</p>
{{object}}
{% if previous_lesson %}
Back
{% endif %}
{% if next_lesson %}
Next
{% endif %}
{% else %}
<h3>Upgrade membership</h3>
<p>To view this course you'll need to upgrade your membership</p>
<br>
<hr>
{% endif %}
</div>
</div>
</div>
{% endblock content %}
As I can see here, you can have multiple LessonModule for a single Lesson due to one-to-many relation between Lesson and LessonModule(ForeignKey relation basically). You can fetch all the LessonModules like this(using reverse query):
# view
def get(self, request, course_slug, lesson_slug, *args, **kwargs):
lesson = get_object_or_404(Lesson.objects.select_related('course').prefetch_related('lessonmodule_set'), slug=lesson_slug, course__slug=course_slug)
context = {
'object': lesson,
'previous_lesson': lesson.get_previous_by_created_at,
'next_lesson': lesson.get_next_by_created_at,
}
return render(request, "courses/lesson_detail.html", context)
# template
{% for lesson_module in object.lessonmodule_set.all %}
{{ lesson_module.slug }}
{% endfor %}
I am just sending the Lesson object to template, and using reverse query in template to get LessonModule objects.
My model looks like this:
class ComicSeries(models.Model):
"""Model definition for ComicSeries."""
# TODO: Define fields here
user = models.ForeignKey(User, on_delete=models.CASCADE,
null=True, blank=True, verbose_name='Uploaded by: '
)
title = models.CharField(verbose_name='Series Title', max_length=500)
cover = models.ImageField(verbose_name='Series cover', upload_to='comic_series',
height_field=None, width_field=None, max_length=None
)
description = models.TextField(verbose_name='Description')
artist = models.CharField(verbose_name='Artist(s)', max_length=500)
date_uploaded = models.DateTimeField(auto_now_add=True)
slug = models.SlugField(default='')
class ComicIssue(models.Model):
"""Model definition for ComicIssue."""
# TODO: Define fields here
user = models.ForeignKey(User, on_delete=models.CASCADE,
null=True, blank=True, verbose_name='Uploaded by: '
)
title = models.ForeignKey(ComicSeries, on_delete=models.CASCADE, verbose_name='Series Title')
issue = models.CharField(verbose_name='Issue Number', max_length=500)
issue_title = models.CharField(verbose_name='Issue Title', max_length=1000)
issue_cover = models.ImageField(verbose_name='Issue cover', upload_to='comic_issues', height_field=None, width_field=None, max_length=None)
issue_description = models.TextField(verbose_name='Description')
issue_file = models.FileField(verbose_name='Issue file', upload_to='comic_issues_files', max_length=100,
help_text='File in pdf or as single image'
)
is_favorite = models.BooleanField(default=False)
issue_slug = models.SlugField(default='')
views.py :
class ComicIssueCreate(LoginRequiredMixin, CreateView):
model = ComicIssue
fields = ['issue_title', 'issue_cover', 'issue_description', 'issue_cover', 'issue_file']
def form_valid(self, form):
form.instance.user = self.request.user
return super(ComicIssueCreate, self).form_valid(form)
I am able to select to which ComicSeries a ComicIssue belongs to in Django admin.
In django admin there is an option to upload
But on my form, there is no field when I add 'title'
Template:
{% block body %}
<div class="container">
<h2>Add new comic issue/chapter</h2>
<form class="form", action="", method="POST", enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="form-group form">
<span class="text-danger small">
{{field.errors}}
</span>
</div>
<label class="control-label col-sm-2">
{{field.label_tag}}
{{field.help_text}}
</label>
<div class="col-sm-10">{{field}}</div>
{% endfor %}
<button type="submit" class="btn grey-text black">Add</button>
</form>
</div>
{% endblock body %}
But I have a problem doing this in a custom form. Is there a way I can determine to which series an issue belongs to in a custom form using CreateView?
You missed 'title' in the fields specified in the view. Since title is the foreign key of ComicIssue to ComicSeries, You need to include that in the fields to achieve whats required
class ComicIssueCreate(LoginRequiredMixin, CreateView):
model = ComicIssue
fields = ['title', 'issue_title', 'issue_cover', 'issue_description',
'issue_cover', 'issue_file']
def form_valid(self, form):
form.instance.user = self.request.user
return super(ComicIssueCreate, self).form_valid(form)
Updates:
The problem was due to not initializing the 'select' in MaterializeCSS. It is necessary to select field to work in MaterializeCSS
<script>
$(document).ready(function() {
$('select').material_select();
});
</script>
The fields in ComicIssueCreate should include title
So fields = ['title','issue_title', 'issue_cover', 'issue_description', 'issue_cover', 'issue_file']