I have to fetch the usernames of my authors' posts
Here the views.py:
from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse
from django.forms import inlineformset_factory
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from django.utils import timezone
from .forms import CreateUserForm
from .models import Post
from .forms import PostForm
def counter(request):
authors = Post.objects.values_list('author', 'title')
authors_id = Post.objects.values_list('author')
authors_name = User.objects.get(id=authors_id)
context = {'authors':authors, 'authors_name':authors_name}
return render(request, 'account/counter.html', {'authors': authors})
My models.py is:
from django.db import models
from django.conf import settings
from django.utils import timezone
# Create your models here.
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
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
And here my forms.py:
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User
from .models import Post
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username','email','password1','password2','user_permissions','is_staff','date_joined']
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'text', 'author']
Now the problem is that on 'authors_id' I have this Error: The QuerySet value for an exact lookup must be limited to one result using slicing, or if i get just one result value of the list the answer's error is: Field 'id' expected a number but got (3,).
So because it takes also the comma from 'values_list'.
I've to got back each author's post and the title of each post the author wrote.
How can I slice the queryset's list?
try this
authors_id = Post.objects.values_list('author', flat=True)
authors_name = User.objects.get(id__in=authors_id)
or
authors_id = Post.objects.values_list('author', flat=True)[0]
authors_name = User.objects.get(id=authors_id)
Refer this https://docs.djangoproject.com/en/3.1/topics/db/queries/#the-pk-lookup-shortcut
Related
I have a class-based view that returns all the data in the table. But while accessing the URL all I get is an empty list.
models.py
from django.db import models
class EmployeeModel(models.Model):
EmpID = models.IntegerField(primary_key=True)
EmpName = models.CharField(max_length=100)
Email = models.CharField(max_length=100)
Salary = models.FloatField()
class Meta:
verbose_name = 'employeetable'
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import EmployeeModel
from .serializers import EmployeeSerialize
class EmployeeTable(APIView):
def get(self,request):
emp_obj = EmployeeModel.objects.all()
empserializer = EmployeeSerialize(emp_obj,many=True)
return Response(empserializer.data)
serializers.py
from rest_framework import serializers
from .models import EmployeeModel
class EmployeeSerialize(serializers.ModelSerializer):
class Meta:
model = EmployeeModel
fields = '__all__'
urls.py
from django.contrib import admin
from django.urls import path, include
from .views import EmployeeTable, transformer_list
urlpatterns = [
path('display/',EmployeeTable.as_view()),
]
The table has 5 rows. It is not empty.
I want to serialize all 5 rows
I have also created the same but in my case, it worked see the below images
See my serializer
See my models below
and my output is here below
I think there are some issue at your code or some mistake can be there can you please provide full information
Here is views.py code.
In the def index section, I use UserInfo model.Here information store in one to one relation so I write (user__pk=user_id)
from django.shortcuts import render
from Login_app.forms import UserForm, UserInfoForm
from Login_app.models import UserInfo
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
from django.urls import reverse
def index(request):
dict={}
if request.user.is_authenticated:
current_user = request.user
user_id = current_user.id
user_basic_info = User.objects.get(pk=user_id)
user_more_info = UserInfo.objects.get(user__pk=user_id)
dict = {'user_basic_info':user_basic_info, 'user_more_info':user_more_info}
return render(request, 'Login_app/index.html', context=dict)
Here is models.py code.where I create UserInfo model.It store user,facebook_id,profile_pc.
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
facebook_id = models.URLField(blank=True)
profile_pic = models.ImageField(upload_to = 'profile_pics', blank=True)
def __str__(self):
return self.user.username
Make Sure that you have inserted data in UserInfo table. For getting date related to one to one field with User table, you don't have to extract user id explicitly. The following code should do it-
current_user = request.user
user_more_info= UserInfo.objects.filter(user=current_user).get()
Moreover, if you have a field called 'full_name' in User model, you can directly access it -
user_full_name=current_user.full_name
So I'm trying to enable the currently logged in user to delete their own post on my site. I'm using a DeleteView with select_related mixing. I keep getting an error that says it's improperly configured and needs to be a tuple or a list. Here is the error, my post models, and views. Not really sure where to go from here, and this doesn't seem to be a very popular error as I'm not really able to find much with a Google search.
Error:
ImproperlyConfigured at /colorsets/delete/7/
DeletePost's select_related property must be a tuple or list.
App Views.py
from django.shortcuts import render
from colorsets.forms import ColorForm
from colorsets import models
from colorsets.models import ColorSet
from django.utils import timezone
from django.contrib.auth import authenticate,login,logout
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse,reverse_lazy
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from braces.views import SelectRelatedMixin
from django.views.generic import (TemplateView,ListView,
DetailView,CreateView,
UpdateView,DeleteView)
# Create your views here.
#def index(request):
# return render(request,'index.html')
class PostListView(ListView):
model = ColorSet
def get_queryset(self):
return ColorSet.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
class CreateColorSetView(LoginRequiredMixin,CreateView):
login_url = '/login/'
redirect_field_name = 'index.html'
form_class = ColorForm
model = ColorSet
def form_valid(self,form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return super().form_valid(form)
class DeletePost(LoginRequiredMixin,SelectRelatedMixin,DeleteView):
model = models.ColorSet
select_related = ('user')
success_url = reverse_lazy('index')
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user_id=self.request.user.id)
def delete(self,*args,**kwargs):
messages.success(self.request,'Post Deleted')
return super().delete(*args,**kwargs)
App models.py
from django.db import models
from django.core.urlresolvers import reverse
from django.conf import settings
from django.contrib.auth import get_user_model
User = get_user_model()
# Create your models here.
class ColorSet(models.Model):
user = models.ForeignKey(User,related_name='colorset')
published_date = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=50,blank=False)
color_one = models.CharField(max_length=6,blank=False,default='cccccc')
color_two = models.CharField(max_length=6,blank=False,default='ffffff')
color_three = models.CharField(max_length=6,blank=False,default='e5e5e5')
color_four = models.CharField(max_length=6,blank=False,default='f0f0f0')
color_five = models.CharField(max_length=6,blank=False,default='bababa')
def publish(self):
self.save()
def get_absolute_url(self):
return reverse('index')
def __str__(self):
return self.name
Traceback:
Let me know if you need to see anything else.
You are missing the comma to make select_related a tuple.
select_related = ('user',)
Without the comma, ('user') is the string 'user'.
I am gettting this error although I am giving proper string in Text and Title fields.I don't know what are the reasons,However i am able to post the values of remaining three fields(author,Created_date,publish_date).
Serializer.py
from rest_framework import serializers
from blog.models import Post
from django.utils import timezone
from rest_framework.validators import UniqueValidator
class blogSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('author','title', 'text','created_date','published_date')
model.py
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey('auth.User',null=True)
title = models.CharField(max_length=200)
text = models.CharField(max_length=200)
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
views.py
from blog.models import Post
from .serializers import UserSerializer, GroupSerializer,blogSerializer
from rest_framework import viewsets,status
from rest_framework.decorators import api_view
class blogViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = blogSerializer
here i am posting the data.
#api_view(['GET', 'POST'])
def blog_list(request):
if request.method=='GET':
my_blog=Post.objects.all()
serializers=blogSerializer(my_blog,Many=True)
return JsoResponse(serializers.data,safe=False)
elif request.method=='POST':
data=JSONParser().parse(request)
serializers=blogSerializer(data=data)
if serializers.is_valid():
serializer.save()
return JsonResponse(serializers.data,status=201)
return JsonResponse(serializers.errors,status=400)
I would set up a unit test to test this functionality. It looks like none of your post data is getting to the serializer otherwise the valid fields would have been repopulated once you submit the form and the for is returned with errors. The title and text fields are also the only fields which are required/do not have a default value.
If you are using some form of decorator(or something similar) on the view which accesses request.data, this might be what is causing the issue. Since rest framework modifies request.POST when populating request.data
I'm making my first DRF api I get a strange AttributeError that I don't understand. When I try to access to my data using a GET request, I get this error:
Got AttributeError when attempting to get a value for field nom on
serializer ExpediteurSerializer. The serializer field might be named
incorrectly and not match any attribute or key on the type instance.
Original exception text was: type object 'QuerySet' has no attribute
'nom'.
I guess I've done something unexpected in my serializers.py file.. Here follows some snippets of my code.
models.py
from django.db import models
# Create your models here.
class Expediteur(models.Model):
nom = models.CharField(max_length=50)
prenom = models.CharField(max_length=100)
adresse = models.CharField(max_length=200)
tel = models.IntegerField()
views.py
from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from polls.serializers import ExpediteurSerializer, DestinataireSerializer, LettrePrioSerializer, TypeLettreRecoSerializer, LettreRecoSerializer, TimbrePrioSerializer, TimbreRecoSerializer
from polls.models import Expediteur, Destinataire, LettrePrio, TypeLettreReco, LettreReco, TimbrePrio, TimbreReco
from rest_framework import status, HTTP_HEADER_ENCODING
from django.shortcuts import render, get_object_or_404
import json
import datetime
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render, get_object_or_404
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth import login
from django.core.exceptions import ObjectDoesNotExist
from django.views.decorators.csrf import csrf_exempt
from django.utils.timezone import get_current_timezone
# Create your views here.
class ExpeViewSet(APIView):
serializer_class = ExpediteurSerializer
def get(self, request):
queryset = Expediteur.objects.all()
serializer = ExpediteurSerializer(queryset)
return Response(serializer.data)
def post(self, request):
serializer = self.serializer_class(data=request.DATA)
return Response(status=status.HTTP_201_CREATED)
serializers.py
from rest_framework import serializers
from polls.models import Expediteur, Destinataire, LettrePrio, TypeLettreReco, LettreReco, TimbrePrio, TimbreReco
class ExpediteurSerializer(serializers.Serializer):
nom = serializers.CharField(required=True, allow_blank=False, max_length=50)
prenom = serializers.CharField(required=True, allow_blank=False, max_length=100)
adresse = serializers.CharField(required=True, allow_blank=False, max_length=200)
tel = serializers.IntegerField(required=True)
def create(self, validated_data):
return Expediteur.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.nom = validated_data.get('nom', instance.nom)
instance.prenom = validated_data.get('prenom', instance.prenom)
instance.adresse = validated_data.get('adresse', insatnce.adresse)
instance.tel = validated_data.get('tel', instance.tel)
instance.save()
return instance
I think you are missing the many flag in you view, like so:
ExpediteurSerializer(queryset, many=True)
In general you could simplify your code very much by fully utilizing DRF.
First, make ExpediteurSerializer a ModelSerializer according to the documentation.
Then you can also get rid of the create and update method, DRF takes care of all of that for you. And I strongly recommend you to look at ModelViewSets, they make your life very easy.