ValueError: Cannot assign "'1'": "Post.user" must be a "User" instance - django

I am doing a group project for a bootcamp and we just started Django for the back-end. We also are using React for front-end. Our project is basically a knockoff reddit.
We have a User model:
`from django.db import models
class User(models.Model):
firstname = models.CharField(max_length=100)
lastname = models.CharField(max_length=100)
email = models.CharField(max_length=100, unique=True)
username = models.CharField(max_length=32, unique=True)
password = models.CharField(max_length=255)
def __str__(self):
return '%s' % (self.username)`
and a Post model:
`from django.db import models
from auth_api.models import User
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
title = models.CharField(max_length=255)
formBody = models.TextField(null=True, blank=True)
imageURL = models.CharField(max_length=200, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)`
Our Post Serializers(pretty unfamiliar with this):
`from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
user = serializers.CharField(required=True)
class Meta:
model = Post
fields = ('id', 'user', 'title', 'formBody', 'imageURL', 'created',)`
And our Post Views:
`from django.shortcuts import render
from rest_framework import generics
from .serializers import PostSerializer
from .models import Post
from auth_api.models import User
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all().order_by('id')
serializer_class = PostSerializer
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all().order_by('id')
serializer_class = PostSerializer`
The idea was when a user created a post their info would be saved with the post so that way when we display the post we could say who created at. Also we could have a user profile that could see all of their posts. I assumed that what would happen is the user info would get saved inside a object in the user column, but the first way we tried only saved the userID and we couldn't access any of the users info. The second way(what we have now) keeps giving us this error: ValueError: Cannot assign "'1'": "Post.user" must be a "User" instance.The 1 is the userID that we pass in from the frontend of the user that created the post. I am unsure of where to go from here and have been stuck for a while on this. Hopefully I provided enough info

Related

NOT NULL constraint failed: shipping_ship.user_id Django

So I'm working on a shipping website with the django rest framework. The website brings two to four people together so they can easily ship their goods together at the same time. But I'm facing a major stumbling block on the views where user book a shipping the code is below.
models.py
from django.db import models
from django.contrib import get_user_model
User = get_user_model()
class Container(models.Model):
container_type = models.Charfield(max_length = 30, blank=False, null = False)
max_users = models.IntegerField()
price = models.DecimalField(max_digits=10, decimal_places =2, default=0, blank=True, null=True)
users = models.ManyToManyField(User)
class Ship(models.Model):
container = models.ForeignKey(Container, related_name='cont', on_delete=models.CASCADE)
user = models.ForeignKey(User, related_name='shipper', on_delete=models.CASCADE)
location = (
('France', 'France'),
)
from_location = models.CharField(max_length=30, choices=location, blank=False, null=False)
to_location = (
('Lagos', 'Lagos'),
('Abuja', 'Abuja'),
('Abeokuta', 'Abeokuta'),
('Osun', 'Osun'),
)
to_location = models.CharField(max_length=30, choices=to_location, blank=False, null=False)
date_leaving = models.DateField(auto_now=False)
price = models.DecimalField(max_digits=10, decimal_places=2, default=0, blank=True, null=True)
def __str__(self):
return self.user
then my serializer.py file
from rest_framework import serializers
from .models import Container, Ship
class ContainerSerializer(serializers.ModelSerializer):
class Meta:
model = Container
fields = '__all__'
class MiniContainerSerializer(serializers.ModelSerializer):
class Meta:
model = Container
fields =['container_type', 'price']
class ShipSerializer(serializers.ModelSerializer):
class Meta:
model = Ship
fields = '__all__'
read_only_fields = ('user', 'price')
class MiniShipSerializer(serializers.ModelSerializer):
class Meta:
model = Ship
fields = ['container', 'from_location', 'to_location']
and now my views.py file which I have issues with
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from rest_framework.generics import ListCreateAPIView, CreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView, RetrieveAPIView
from .serializers import ContainerSerializer, MiniContainerSerializer, ShipSerializer, MiniShipSerializer
from rest_framework import permissions, status
from rest_framework.response import Response
from .models import Container, Ship
class ShipAPI(ListCreateAPIView):
serializer_class = ShipSerializer
def get_queryset(self):
user = self.request.user
queryset = Ship.objects.filter(user=user)
return queryset
def Book_shipping(self, request, *args, **kwargs):
user = request.user
container = get_object_or_404(Container, pk=request.data['container'])
if container.users.count() >= container.max_users:
return Response('container already full')# here i'm trying to set limits so the users joining each container won't surpass the max users.
cont = container(users=user)
cont.save()
from_location = (request.data['from_location'])
to_location = (request.data['to_location'])
date_leaving = int(request.data['date_leaving'])
price = container.price / container.max_users
cart = Ship(container=container, user=user, from_location=from_location, to_location=to_location, date_leaving=date_leaving, price=price)
cart.save()
serializer = ShipSerializer(cart)
data ={'message': 'shipping successfully created',
'data':serializer.data}
return Response(data=data, status=status.HTTP_201_CREATED)
and then after testing the endpoint it returns this error:
IntegrityError at /Shipping/Ship/
NOT NULL constraint failed: shipping_ship.user_id
I've tried debugging and looking at it over and over again can someone please help me? Thanks in advance. And yes I've tried deleting migrations and the database.
As your Container model have a ManyToMany relationship with the User model.
So it may not work like cont = container(users=user)
For me it worked like this:
cont = container.users.add(user)
cont.save()

making an API that adds instances to ManyToMany fields of a model in django rest framework

I am making a movie watching website in which there are users and films and the user model has a ManyToMany Field that references the film model. it's called WatchList and an authenticated user can add any movie they want to this watchlist.
My problem is that I want an API that only gets the ID of a film and adds it to the user's watch list.
these are my models and serializers and I am trying to make a view to implement this API.
# models.py
class Film(models.Model):
filmID = models.AutoField(primary_key=True)
title = models.CharField(max_length=150)
# ...
class User(AbstractBaseUser, PermissionsMixin):
userID = models.AutoField(primary_key=True)
username = models.CharField(max_length=100, unique=True, validators=[RegexValidator(regex="^(?=[a-z0-9._]{5,20}$)(?!.*[_.]{2})[^_.].*[^_.]$")])
email= models.EmailField(max_length=100, unique=True, validators=[EmailValidator()])
name = models.CharField(max_length=100)
watchList = models.ManyToManyField(Film)
objects = UserManager()
USERNAME_FIELD = 'username'
# serializers.py
class WatchListSerializer(serializers.ModelSerializer):
class FilmSerializer(serializers.ModelSerializer):
model = Film
fields = ('filmID', 'title',)
read_only_fields = ('filmID', 'title')
film_set = FilmSerializer(read_only=True, many=True)
class Meta:
model = get_user_model()
fields = ('userID', 'film_set')
read_only_fields = ('userID',)
# views.py
class WatchListAddView(...):
pass
The serializer can be changed. but this kind of shows what I want the api to be. the authentication validation part is already taken care of, so imagine that any request to the view is from an authenticated user.
I would not recommend patching this directly and instead create a separate endpoint for adding removing data to this field.
In your case it would look like this. I show just a small working example, you can adjust it to your needs
from django.shortcuts import get_object_or_404
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
#action(detail=True,
methods=['POST'])
def add_film_to_watch_list(self, request, **kwargs):
film = get_object_or_404(klass=Film, filmID=kwargs.get('filmID'))
user = self.get_object()
user.watchList.add(film)
return Response("Success")

Cannot access field in Django Graphene

The field which is specified in my models file is not included in the GraphiQL, I have tried to rename the field, delete it and define it again, even changing the type of field also updating the graphene-django package. None of these I have mentioned didn't work. The name of the field I can't get is named book
models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from books.models import Book
class Borrowing(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
book = models.OneToOneField(Book, null=True, on_delete=models.CASCADE)
date = models.DateTimeField(default=timezone.now)
returned = models.BooleanField(default=False)
date_borrowed = models.CharField(blank=True, null=True, max_length=50)
date_returned = models.CharField(blank=True, null=True, max_length=50)
class Meta:
ordering = ['-date']
def __str__(self):
return f'{self.user.username} borrowed {self.book.title}'
schema.py
import graphene
from .mutations.borrowings import *
from backend.functions import pagination
PAGE_SIZE = 12
class BorrowingMutation(graphene.ObjectType):
borrow_book = BorrowBook.Field()
return_book = ReturnBook.Field()
class BorrowingQuery(graphene.ObjectType):
borrowings = graphene.List(BorrowingType)
users_borrowings = graphene.List(BorrowingType, page=graphene.Int())
def resolve_borrowings(self, info):
return Borrowing.objects.all()
def resolve_users_borrowings(self, info, page):
user = info.context.user
borrowings = Borrowing.objects.filter(user=user, returned=False)
borrowings = pagination(PAGE_SIZE, page, borrowings)
return borrowings
Type
class BorrowingType(DjangoObjectType):
class Meta:
model = Borrowing

how to create tag field in django form like youtube have

i want to create a tag field like youtube give tage field while uploading a vedio this is what i tried in in my blog form
my models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
# Create your models here.
class Blog(models.Model):
author = models.OneToOneField(User, on_delete=models.CASCADE,)
title = models.CharField(max_length=200,blank=False,)
thumbnail = models.ImageField(upload_to='blogs_thumbnail',default='blogdefa.png')
tags = models.CharField(max_length=500, blank=False, default='Blog')
data = models.TextField(blank=False,)
published_date = models.DateTimeField(default=timezone.now,editable=False)
update_at = models.DateTimeField(auto_now=True,editable=False)
def __str__(self):
return self.title
any idea how to do it i don,t know how to do it
my forms.py
from django import forms
from django.forms import ModelForm, Textarea
from django.contrib.auth.models import User
from .models import Blog, comment, report
forms here
class BlogForm(forms.ModelForm):
class Meta:
model = Blog
fields = '__all__'
widgets = {'data': Textarea(attrs={'cols': 80, 'rows': 20, 'placeholder':'Write Here'}),
'title':forms.TextInput(attrs={'placeholder':'Your Blog Title Here'}),
'tags': forms.TextInput(attrs={'placeholder':'Please enter you content related tags'}),
}
exclude = ['author','published_date','update_at']
all i want is user can create his own tag for blogs like in youtube and not like stackoverflow where you have use to choose you tag
please help
currently it look like this
which is not cool
First thing is that tags work. So to get them working you should relate it to your post.
So you should create a Tag model and use a ManytoManyRelated field to relate tags because you need to get to the post/result at the end using tags.
from django.db import models
from django_extensions.db.fields import AutoSlugField
from django.db.models import CharField, TextField, DateField, EmailField, ManyToManyField
class Tag(models.Model):
name = CharField(max_length=31, unique=True, default="tag-django")
slug = AutoSlugField(max_length=31, unique=True, populate_from=["name"])
def __str__(self):
return self.name
class YourPost(models.Model):
name = CharField(max_length=31, db_index=True)
slug = AutoSlugField(max_length=31, unique=True, populate_from=["name"])
description = TextField()
date_founded = DateField(auto_now_add=True)
contact = EmailField()
tags = ManyToManyField(Tag, related_name="tags")
class Meta:
get_latest_by = ["date_founded"]
def __str__(self):
return self.name
Go on from here.
Create serializers, Viewsets. Relate your tags to your post.

Django model of a rent contract using Generic Foreign Key

I'm trying to model a rent contract in Django and use the admin form to insert and modify it.
Both owner and tenant can be companies (VAT number) or individuals (no VAT number). Companies and individuals are stored in two different models (Company and Individual).
I'm trying to solve this problem using Generic Foreign Key but I'm not able to show the tenant name in the admin page, only an integer field not friendly at all.
gestimm is the name of the app and that's my oversimplified models:
# my gestimm/models.py
#
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
class Individual(models.Model):
name = models.CharField(max_length=100, help_text='Name')
def __str__(self):
return self.name
class Company(models.Model):
name = models.CharField(max_length=100, help_text='Name')
def __str__(self):
return self.name
class Contract(models.Model):
description = models.CharField(max_length=30)
start = models.DateField()
stop = models.DateField()
def __str__(self):
return self.description
class Tenant(models.Model):
limit = models.Q(app_label='gestimm', model='individual') | models.Q(app_label='gestimm', model='company')
contract = models.ForeignKey(Contract, on_delete=models.CASCADE,
null=True, blank=True)
content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT,
help_text='Tenant', null=True,
limit_choices_to=limit)
object_id = models.PositiveIntegerField(null=True)
tenant = GenericForeignKey('content_type', 'object_id')
How I tried to solve the problem:
# my gestimm/admin.py
#
from django.contrib import admin
from .models import Individual, Company, Contract, Tenant
class TenantInline(admin.StackedInline):
model = Tenant
extra = 1
class ContractAdmin(admin.ModelAdmin):
inlines = [TenantInline]
admin.site.register(Individual)
admin.site.register(Company)
admin.site.register(Contract, ContractAdmin)
I found some old discussions but none of the proposed solutions worked.
Problem solved: I installed django-grappelli.
My new admin.py:
class TenantInline(admin.TabularInline):
model = Tenant
extra = 1
related_lookup_fields = {
'generic': [['content_type', 'object_id']],
}
class ContractAdmin(admin.ModelAdmin):
inlines = [
TenantInline,
]
admin.site.register(Contract, ContractAdmin)
As intended