__str__ returned non-string (type Category). when I add post from admin - django-models

After I added user and date_added in the Photo models, when I add post from admin its throws me an error saying: str returned non-string (type Category), when I click on the addpost link in the home template its throw another error: 'tuple' object has no attribute 'name'. how can I solve that ?
the models.py:
from django.db import models
from cloudinary.models import CloudinaryField
from django.contrib.auth.models import User
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=100, null=False, blank=False)
def __str__(self):
return self.name
class Photo(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True,
blank=True)
image = CloudinaryField('image')
description = models.TextField(null=True)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.category
the view.py file:
def home(request):
category = request.GET.get('category')
if category == None:
photos = Photo.objects.all()
else:
photos = Photo.objects.filter(category__name=category)
categories = Category.objects.all()
context = {'categories': categories, 'photos': photos}
return render(request, 'home.html', {'categories': categories, 'photos': photos} )
def viewPhoto(request, pk):
photo = Photo.objects.get(id=pk)
return render(request, 'photo.html', {'phpto': photo})
class PostCreativeView(LoginRequiredMixin, CreateView):
model = Photo, Category
fields = ['description', 'image', 'category', 'name']
template_name = 'post_create.html'
def form_valid(self, form):
form.instance.user = self.request.user
return super (PostCreativeView, self).form_valid(form)

Well it has to do with your category name and model you added into post create view.py and so you
have do something like this:
views.py
class PostCreativeView(LoginRequiredMixin, CreateView):
model = Photo
fields = ['description', 'image', 'category']
template_name = 'post_create.html'
def form_valid(self, form):
form.instance.user = self.request.user
return super (PostCreativeView, self).form_valid(form)
#.......
# Models.py
class Photo(models.Model):
#>>>...
def __str__(self):
return str(self.category)

You should return the str(…) of the category, so:
class Photo(models.Model):
# …
def __str__(self):
return str(self.category)

Related

Cannot access database instances with id=pk

Here is my views.py file. I input the required fields through form like this:
from django.shortcuts import render, redirect
from .models import nekor_Table
from .forms import user_form
def home(request):
user_form_obj = user_form()
if request.method == "POST":
form = user_form(request.POST)
if form.is_valid():
form.save()
else:
form = user_form_obj()
context = {'user_form_obj': user_form_obj}
return render(request, 'polls/home.html', context )
def nav(request):
return render(request, 'navbar.html')
def display(request, pk):
display_table_obj = nekor_Table.objects.get(id=pk)
context = {'display_table_obj': display_table_obj}
return render(request, 'polls/display_page.html', context)
i have two tables and when i try to get individual instance with id=pk, and running http://127.0.0.1:8000/display/1/ in my browser it gives me: nekor_Table matching query does not exist, error. what am i missing here? this was working just fine in my previous project but doesnt work in this one.
here is my urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('index/', views.home, name='home'),
path('navbar/', views.nav, name='navbar'),
path('display/<int:pk>/', views.display, name='display')
]
and here is my models.py
from django.db import models
from django.contrib.auth.models import User
class nekor_Table(models.Model):
title = models.CharField(max_length=200, null=True, blank=False)
place = models.CharField(max_length=200, null=True, blank=False)
deity = models.CharField(max_length=200, null=True, blank=False)
description = models.TextField(null=True, blank=False)
teachers = models.CharField(max_length=200, null=True, blank=False)
architecture = models.CharField(max_length=200, null=True, blank=False)
def __str__(self):
return self.title

Django Post request for many to many field ValueError

I am working on a post request in which the user chooses from a list of tags and makes combinations of tags. The combination of tags should then be posted. Nothing should get changed in the Tag table.
These are the models:
models.py
class Tag(models.Model):
name = models.CharField(max_length=256)
language = models.CharField(max_length=256)
objects = models.Manager()
def __str__(self):
"""Return a human readable representation of the model instance."""
return self.name or ''
#property
def tags(self):
tags = self.tagging.values('tag')
return tags.values('tag_id', 'tag__name', 'tag__language')
class Combination(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
gameround = models.ForeignKey(Gameround, on_delete=models.CASCADE, null=True)
resource = models.ForeignKey(Resource, on_delete=models.CASCADE, null=True)
tag_id = models.ManyToManyField(Tag, null=True)
created = models.DateTimeField(editable=False)
score = models.PositiveIntegerField(default=0)
objects = models.Manager()
def __str__(self):
return str(self.tag_id) or ''
This is the serializer for Combination.
serializers.py
class CombinationSerializer(serializers.ModelSerializer):
tag_id = TagWithIdSerializer(many=True, required=False, write_only=False)
resource_id = serializers.PrimaryKeyRelatedField(queryset=Resource.objects.all(),
required=True,
source='resource',
write_only=False)
gameround_id = serializers.PrimaryKeyRelatedField(queryset=Gameround.objects.all(),
required=False,
source='gameround',
write_only=False)
user_id = serializers.PrimaryKeyRelatedField(queryset=CustomUser.objects.all(),
required=False,
source='user',
write_only=False)
class Meta:
model = Combination
depth = 1
fields = ('id', 'user_id', 'gameround_id', 'resource_id', 'tag_id', 'created', 'score')
def create(self, validated_data):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
score = 0
tag_data = validated_data.pop('tag_id', None)
combination = Combination(
user=user,
gameround=validated_data.get("gameround"),
resource=validated_data.get("resource"),
created=datetime.now(),
score=score
)
combination.save()
for tag_object in tag_data[0]:
combination.tag_id.add(tag_object)
return combination
def to_representation(self, instance):
rep = super().to_representation(instance)
rep['tag_id'] = TagWithIdSerializer(instance.tag_id.all(), many=True).data
return rep
I have tried posting the following JSON object to the database:
{
"gameround_id": 2015685170,
"resource_id": 327888,
"tag_id": [{"id": 2014077506, "name": "corwn","language": "en"}]
}
I am getting a ValueError: Field 'id' expected a number but got 'name'.
How can I fix this issue?
you need to provide tag id for each tag not all tag data,
Try like this
{
"gameround_id": 2015685170,
"resource_id": 327888,
"tag_id": [2014077506,2014077507]
}

'Account' object has no attribute 'products' AND (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.'

I am following Django rest_framework tutorial to build my app but and I'm using a custom user model (Account) which inherits AbstractBaseUser.
I have another model - Product - and each product is owned by an Account.
My models.py is:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.conf import settings
class Product(models.Model):
owner = models.ForeignKey(Account, related_name='account', on_delete=models.CASCADE, default=1)
name = models.CharField(max_length=71)
product = models.CharField(max_length=20, blank=True)
price = models.IntegerField(null=True, blank=True)
quantity = models.IntegerField(default=0)
image = models.ImageField(upload_to='images', blank=True)
display = models.BooleanField(default=False)
created = models.DateTimeField('date added', auto_now=True)
modified = models.DateTimeField('date modified', auto_now_add=True)
def __str__(self):
return self.name
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError("Please enter a valid email address")
if not username:
raise ValueError("Please enter a username")
user = self.model(
email = self.normalize_email(email),
username = username,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email = self.normalize_email(email),
password = password,
username = username,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name='email', max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last_login', auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_merchant = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = MyAccountManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
My settings.py includes:
AUTH_USER_MODEL = 'accounts.Account'
My serializers.py is:
from rest_framework import serializers
from inventory.models import Product
from accounts.models import Account
class AccountSerializer(serializers.ModelSerializer):
products = serializers.PrimaryKeyRelatedField(many=True, queryset=Product.objects.all())
password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)
class Meta:
model = Account
fields = ['products', 'email', 'username', 'password', 'password2']
extra_kwargs = {
'password': {'write_only': True}
}
def save(self):
account = Account(
email = self.validated_data['email'],
username = self.validated_data['username'],
)
password = self.validated_data['password']
password2 = self.validated_data['password2']
if password != password2:
raise serializers.ValidationError({'password': 'Passwordss must match.'})
account.set_password(password)
account.save()
return account
class ProductSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.email')
class Meta:
model = Product
fields = [
'id', 'owner', 'name', 'product', 'price', 'quantity', 'image', 'display'
]
My views.py is:
from accounts.api.serializers import AccountSerializer
from inventory.api.serializers import ProductSerializer
from inventory.models import Product
from accounts.models import Account
from rest_framework import permissions
from rest_framework import generics
class AccountList(generics.ListAPIView):
queryset = Account.objects.all()
serializer_class = AccountSerializer
class AccountDetail(generics.RetrieveAPIView):
queryset = Account.objects.all()
serializer_class = AccountSerializer
class ProductList(generics.ListCreateAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
queryset = Product.objects.all()
serializer_class = ProductSerializer
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class ProductDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
queryset = Product.objects.all()
serializer_class = ProductSerializer
I am able to view my ProductList and ProductDetail however, I get the following error when I try to view AccountList and AccountDetail:
**Exception Type:** AttributeError
**Exception Value:** 'Account' object has no attribute 'products'
Just change your serailzier like this
class AccountSerializer(serializers.ModelSerializer):
products = serializers.SerializerMethodField()
password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)
def get_products(self, instance):
return Product.objects.all().values_list('id', flat=True)
class Meta:
model = Account
fields = ['products', 'email', 'username', 'password', 'password2']
extra_kwargs = {
'password': {'write_only': True}
}
def save(self):
account = Account(
email = self.validated_data['email'],
username = self.validated_data['username'],
)
password = self.validated_data['password']
password2 = self.validated_data['password2']
if password != password2:
raise serializers.ValidationError({'password': 'Passwordss must match.'})
account.set_password(password)
account.save()
return account
PrimaryKeyRelatedField may be used to represent the target of the relationship using its primary key. The queryset used for model instance lookups when validating the field input. Your field is read_only field. Your should use SerializerMethodField for this.

How can I access my models in django admin?

I am working on an AlumniTracker in django and till now I have created forms for user sign up and some additional information.
Even after saving the additional information form I am not able to access it in django-admin.
I am adding my models, views and forms file here.
views.py
def student_profile(request):
if request.method == 'POST':
form = StudentDetailForm(request.POST)
if form.is_valid:
student_form = form.save(commit=False)
student_form.user = request.user
student_form.save()
return redirect(reverse('homepage'))
else:
form = StudentDetailForm()
return render(request, 'authentication/student_profile.html', {'form':form})
def alumni_profile(request):
if request.method == 'POST':
form = AlumniDetailForm(request.POST)
if form.is_valid:
alumni_form = form.save(commit=False)
alumni_form.user = request.user
alumni_form.save()
return redirect(reverse('homepage'))
else:
form = AlumniDetailForm()
return render(request, 'authentication/student_profile.html', {'form':form})
forms.py
class StudentDetailForm(ModelForm):
class Meta:
model = StudentDetail
fields = ['first_name', 'last_name', 'contact_no', 'birth_date', 'course', 'session_start', 'session_end']
class AlumniDetailForm(ModelForm):
class Meta:
model = AlumniDetail
exclude = ['user']
models.py
class CustomUser(AbstractUser):
profile = models.CharField(max_length=10,choices=PROFILE_CHOICES, default='student')
def __str__(self):
return self.username
class StudentDetail(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
contact_no = models.IntegerField()
birth_date = models.DateField()
course = models.CharField(max_length=50)
session_start = models.IntegerField()
session_end = models.IntegerField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class AlumniDetail(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
contact_no = models.IntegerField()
birth_date = models.DateField()
course = models.CharField(max_length=50)
session_start = models.IntegerField()
session_end = models.IntegerField()
company = models.CharField(max_length=60)
open and edit admin.py
and register your models by adding code below admin import
from .models import CustomUser,StudentDetail,AlumniDetail
admin.site.register(CustomUser)
admin.site.register(StudentDetail)
admin.site.register(AlumniDetail)

NOT NULL constraint failed: IntegrityError

Trying a django project from the documentations.
This is my Models.py I am trying to make a simple employee goals management system. I have also used DRF and serializers, integrated swagger for only doing 'GET' of the models below. I have removed (commented out) all ForeignKey and ManyToMany Fields yet, when I add modify the goal or project I get this error. I cant seem to solve this, please help.
class Department(models.Model):
department_name = models.CharField(max_length=200)
department_location = models.CharField(max_length=200)
department_region = models.CharField(max_length=200)
department_site = models.CharField(max_length=200)
department_job_titles = models.CharField(max_length=200)
def __str__(self):
return self.department_name
class Employee(models.Model):
#department_name = models.ManyToManyField(Department)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email_id = models.CharField(max_length=100)
#employee_id = models.IntegerField()
supervisor_name = models.CharField(max_length=100)
designation = models.CharField(max_length=100)
doj = models.DateTimeField('date joined')
def __str__(self):
return self.first_name
class Objectives(models.Model):
objective_name = models.CharField(max_length=200)
#employee = models.ManyToManyField(Employee)
def __str__(self):
return self.objective_name
class Project(models.Model):
#employee = models.ManyToManyField(Employee)
project_name = models.CharField(max_length=200)
def __str__(self):
return self.project_name
class Goals(models.Model):
goal_id = models.IntegerField()
goal_name = models.CharField(max_length=200)
#department = models.ManyToManyField(Department)
role = models.CharField(max_length=200)
#objective_id = models.ManyToManyField(Objectives)
goal_start = models.DateTimeField('date goal added')
goal_end = models.DateTimeField('date goal ends')
#employee = models.ManyToManyField(Employee)
def __str__(self):
return self.goal_name
This is my views.py
from django.shortcuts import get_object_or_404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Employee
from .models import Goals
from .models import Objectives
from .models import Department
from .models import Project
from .serializers import EmployeeSerializer
from .serializers import ProjectSerializer
from .serializers import GoalsSerializer
from .serializers import ObjectivesSerializer
from .serializers import DepartmentSerializer
from django.http import HttpResponse
from rest_framework_swagger.views import get_swagger_view
schema_view = get_swagger_view(title='UpYourGame API')
#just a view if someone hits the index
def index(request):
return HttpResponse("Hello and Welcome to UpyourGame")
# this will be the URL /employee/
class Employee(APIView):
def get(self, request):
employee = Employee.objects.all()
serializer = EmployeeSerializer(employee, many=True)
return Response(serializer.data)
class Project(APIView):
def get(self, request):
project = Project.objects.all()
serializer = ProjectSerializer(project, many=True)
return Response(serializer.data)
class Goals(APIView):
def get(self, request):
goals = Goals.objects.all()
serializer = GoalsSerializer(goals, many=True)
return Response(serializer.data)
class Objectives(APIView):
def get(self, request):
objectives = Objectives.objects.all()
serializer = ObjectivesSerializer(objectives, many=True)
return Response(serializer.data)
#class Company(APIView):
# def get(self, request):
# company = Company.objects.all()
# serializer = CompanySerializer(company, many=False)
# return Response(serializer.data)
class Department(APIView):
def get(self, request):
department = Department.objects.all()
serializer = DepartmentSerializer(Department, many=True)
return Response(serializer.data)
This is myproject/urls.py
from django.conf.urls import include, url
from django.contrib import admin
from enterprise import views
urlpatterns = [
url(r'^$', views.schema_view, name='schema_view'),
url(r'^enterprise/', include('enterprise.urls')),
url(r'^admin/', admin.site.urls),
url(r'^employee/', views.Employee.as_view()),
url(r'^goals/', views.Goals.as_view()),
url(r'^department/', views.Department.as_view()),
url(r'^department/', views.Department.as_view()),
url(r'^objectives/', views.Objectives.as_view()),
url(r'^project/', views.Project.as_view()),
]
This is my serializers.py
from rest_framework import serializers
from .models import Employee
from .models import Goals
from .models import Objectives
from .models import Department
from .models import Project
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = '__all__'
#class EmployeeDetailsSerializer(serializers.ModelSerializer):
# class Meta:
# model = EmployeeDetails
# fields = '__all__'
class ObjectivesSerializer(serializers.ModelSerializer):
class Meta:
model = Objectives
fields = '__all__'
class DepartmentSerializer(serializers.ModelSerializer):
class Meta:
model = Department
fields = '__all__'
#class CompanySerializer(serializers.ModelSerializer):
# class Meta:
# model = Company
# fields = '__all__'
class GoalsSerializer(serializers.ModelSerializer):
class Meta:
model = Goals
fields = '__all__'
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
The SQLlite DB was corrupt due to too many migrations, it can happen. I deleted SQLlite and all my migrations, I retried migrate, makemigrate and sqlmigrate, it resolved the issue.
If you run into a similar issue in a dev environment please try the following
1. Delete all your migrations in the migrations folder
2. Delete db.sqlite3
3. Run python manage.py migrate
4. Run python manage.py makemigrations
5. Run python manage.py sqlmigrate appname 0001
This will fix this issue.

Resources