When I submit a new team as a authenticated user, I get this error is showing. I searched a lot of answers but they say do it null=True or default=1 but I don't want to be it null or something I want to be user's id it. Plus I imported and tried settings.AUTH_USER_MODEL and get_user_model
from django.contrib.auth.models import User
#models.py
class Team(models.Model):
creator = models.ForeignKey(User, related_name='teams', on_delete=models.CASCADE)
name = models.CharField(max_length=20, unique=True)
rank = models.IntegerField(default=0)
#views.py
class TeamsCreateView(generic.CreateView):
model = Team
form_class = TeamCreationForm
#forms.py
class TeamCreationForm(forms.ModelForm):
class Meta:
model = Team
fields = ('name',)
Override the form_valid method, and set user on the form's instance before saving it.
from django.contrib.auth.mixins import LoginRequiredMixin
class TeamsCreateView(LoginRequiredMixin, generic.CreateView):
model = Team
form_class = TeamCreationForm
def form_valid(self, form):
form.user = self.request.user
return super(TeamsCreateView, self).form_valid(form)
Use LoginRequiredMixin to make sure that users can only access the view if they are logged in.
Related
I'm learning django and I made the tutorial on django site. I thought that I could link user to poll that he created but I'm struggling with it. When I'm logged in and creating a poll I can't see user name. In database column author_id has value null. I would appreciate every help.
Here is my code
from django.db import models
from django.utils import timezone
import datetime
from django.contrib import auth
# Create your models here.
User = auth.get_user_model()
class Question(models.Model):
question_text = models.CharField(max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=False)
def __str__(self):
return self.question_text
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
class User(auth.models.User, auth.models.PermissionsMixin):
def __str__(self):
return "#{}".format(self.username)
forms.py:
class UserCreateForm(UserCreationForm):
class Meta:
fields = ('username', 'email', 'password1', 'password2')
model = get_user_model()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Display Name'
self.fields['email'].label = 'Email Address'
class CreatePollForm(forms.ModelForm):
class Meta:
model = Question
fields = ('question_text',)
and views.py
class CreatePoll(LoginRequiredMixin, generic.CreateView):
form_class = forms.CreatePollForm
success_url = reverse_lazy('pollapp:index')
template_name = 'polls/createPoll.html'
Since your CreatePollForm only assigns the question_text field, you need to assign the author in code. A CreateView is a FormView which does the saving of the form in its form_valid() method. So in your CreateView, you want to override that method:
# in class CreatePoll
def form_valid(self, form):
question = form.save(commit=False) # fetch the new question, don't save
question.author = self.request.user # assign the user
question.save() # now save
return super().form_valid(form)
It isn't clear how you could end up with a null value for the author_id, that should have raised an IntegrityError. Are you sure you ran makemigrations and migrate in the current state?
I have this custom user model 'es_user'
models.py
class es_user(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
class es_event(models.Model):
ev_name = models.CharField(max_length=100)
ev_venue = models.CharField(max_length=100)
ev_admin = models.ForeignKey('es_user',related_name='events',on_delete=None)
Eventually, I'll be adding more fields to es_user that's why I used a custom user model. So I cannot settle for django's inbuilt user model.
views.py
class CreateEventView(LoginRequiredMixin,CreateView):
model = es_event
fields = ['ev_name','ev_venue','ev_date','ev_description']
def form_valid(self, form):
form.instance.ev_admin = self.request.user
return super(CreateEventView, self).form_valid(form)
when I submit the form I get this error
Cannot assign "<SimpleLazyObject: <User: randy>>": "es_event.ev_admin" must be a "es_user" instance.
I've checked Django documentation and other stack overflow posts, but in all those the foreign key is referencing Django's inbuilt user model
So just assign the es_user, not the auth user.
form.instance.ev_admin = self.request.user.es_user
You can fetch the es_user instead:
form.instance.ev_admin = es_user.objects.get(user=self.request.user)
everything worked fine when I made some changes to views.py and models.py
views.py
class CreateEventView(LoginRequiredMixin,CreateView):
model = es_event
fields = ['ev_name','ev_venue','ev_date','ev_description']
def form_valid(self, form):
form.instance.ev_admin = self.request.user.es_user
models.py
class es_user(models.Model):
user = models.OneToOneField(User,related_name='es_user', on_delete=models.CASCADE)
I use a generic CreateView to let logged in users (Creator) add objects of the model Piece. Since creating a Piece is done by the Creator (logged in user) there is no need for the CreateView to either show or manipulate the 'creator' field. Hence I wish to not show it and set it to the logged in user. However, approaches such as overwriting form_valid or using get_form_kwargs seem not to get it done. Using the form_valid method gives a ValueError:
Cannot assign "<SimpleLazyObject: <User: patrick1>>": "Piece.creator" must be a "Creator" instance.
The solution seems to be just around the corner, I hope.
Tried but did not work:
form_valid method, form_valid method, get_form_kwargs method
My code:
models.py
class Piece(models.Model):
creator = models.ForeignKey('Creator', on_delete=models.SET_NULL, null=True)
title = models.CharField(max_length=200)
summary = models.TextField(max_length=1000, help_text='Enter a brief description of the Piece')
created = models.DateField(null=True, blank=True)
...
from django.contrib.auth.models import User
class Creator(models.Model):
...
user = models.OneToOneField(User, on_delete=models.CASCADE)
...
views.py
class PieceCreate(LoginRequiredMixin, CreateView):
model = Piece
fields = ['title', 'summary', 'created']
initial = {'created': datetime.date.today()}
def form_valid(self, form):
obj = form.save(commit=False)
obj.creator = self.request.user
return super(PieceCreate, self).form_valid(form)
success_url = reverse_lazy('pieces')
Any suggestions are highly appreciated!
obj.creator = Creator.objects.get(user=self.request.user)
or any other solution that will give you Creator instance for current user instead of User. Just as the error message says.
Cannot assign "User: patrick1": "Piece.creator" must be a "Creator" instance.
I'm trying to link 'owner' field of my model to an AbstractUser. I need it to be done automatically, the only think i'm able to do by myself is to allow user logged in to choice between every existing user with, what's not what i want. I would like to not have a field to manipulate, but a outcome serializer with id or username of User that added the model. I'm trying to find solutions for a few days, I've tried already combine ForeignKey, PrimaryKeys, OneToOneField, HiddenField, get_user, perform_create, but I'm for sure doing something wrong, and i'm almost lost with it. The last thing i tried is to def_perform in views like DRF QuickStart tutorial say, but without results.
I add some code sample to be more understandable:
There is my AbstractUser model:
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserProfile(AbstractUser):
username = models.CharField(max_length=20, unique=True)
...
i added it to AUTH_USER_MODEL = in the settings.
And there is other model which i want to link with User:
from django.db import models
from users.models.user import UserProfile
class MyPhoto(models.Model):
owner = models.ForeignKey(UserProfile, related_name='photos', on_delete=models.CASCADE, null=True)
image = models.ImageField(upload_to='Images')
serializer.py
class MyPhotoSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = MyPhoto
fields = ('pk', 'image', 'owner')
def create(self, validated_data):
photo = MyPhoto.objects.create(
image=validated_data['image']
)
photo.save()
return photo
views.py
class UpdateMyPhotoViewSet(viewsets.ModelViewSet):
queryset = MyPhoto.objects.all()
serializer_class = MyPhotoSerializer
permission_classes = (IsAuthenticated,)
def perform_create(self, serializer):
serializer.save(created_by=self.request.user)
and for now i can't see the owner field results.
Thanks in advance.
I'm making a hobby project and I've got the following model:
from django.contrib.auth.models import User
from django.db import models
class Group(models.Model):
name = models.CharField(blank=False, max_length=25)
description = models.CharField(max_length=50, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=False)
def __str__(self):
return self.name
class Meta:
ordering = ('name', )
# my intention is that one user cannot have more than one group with the same name
unique_together = ('name', 'user')
I would like to make it possible for the user to create new groups by using this generic class based view.
from django.urls import reverse_lazy
from django.views import generic
from groups.models import Group
class GroupCreate(generic.CreateView):
model = Group
fields = [
'name',
'description'
]
success_url = reverse_lazy('ideas:list')
template_name = 'groups/group_create.html'
def form_valid(self, form):
form.instance.user = self.request.user
return super(GroupCreate, self).form_valid(form)
As long as I don't try to make an error by sending an existing group's name, everything works fine. But if I send an existing group's name (same user!), I get the following error:
IntegrityError at /groups/create
UNIQUE constraint failed: groups_group.name, groups_group.user_id
Why does it occur? How could I fix it or catch the error?
I'm using Django 2.0.2
You can check at the time of creating the group.
from django.contrib import messages
def form_valid(self, form):
form.instance.user = self.request.user
name = form.cleaned_data['name']
if Group.objects.filter(name=name, user=self.request.user).exists():
messages.error(self.request, 'An Group with this name already exists.')
return self.render_to_response(self.get_context_data(form=form))
else:
form.instance.name= name
messages.success(self.request, 'Congratulations!! Your Group is created successfully.')
return super(GroupCreate, self).form_valid(form)
This occurs because you declared a constraint:
unique_together = ('name', 'user')
Just remove this constraint.