Getting the post instance in Django class based views - python-3.x

I currently use a function based view to let users write comments on posts, but I'm trying to convert it to class based views
Function views.py
def comment(request, pk):
form = CommentForm(request.POST)
# Post instance
post_instance = get_object_or_404(Post, pk=pk)
if request.method == 'POST':
if form.is_valid:
obj = form.save(commit=False)
obj.commenter = request.user
obj.post = post_instance
obj.save()
return redirect('/')
else:
messages.error(request, 'Comment Failed')
return render(request, 'comment.html', {'form': form})
Class views.py
class CommentView(FormView):
template_name = 'comment.html'
form_class = CommentForm
success_url = '/'
def get_object(self):
pk = self.kwargs.get('pk')
post_instance = get_object_or_404(Post, pk=pk)
return post_instance
def form_valid(self, form):
obj = form.save(commit=False)
obj.commenter = self.request.user
obj.post = post_instance
obj.save()
return super().form_valid(form)
I'm trying to implement the same logic for saving the comment but I get the error: name 'post_instance' is not defined
get_object() is returning the 'post_instance' variable but I can't access it.
Could you guys show me where I'm doing a mistake, thanks in advance!

You can try:
class CommentView(FormView):
template_name = 'comment.html'
form_class = CommentForm
success_url = '/'
def get_object(self):
pk = self.kwargs.get('pk')
post_instance = get_object_or_404(Post, pk=pk)
return post_instance
def form_valid(self, form):
obj = form.save(commit=False)
obj.commenter = self.request.user
obj.post = self.get_object()
obj.save()
return super().form_valid(form)

Related

NOT NULL constraint failed: dashboard_profile.user_id

I'm trying to save the last IP of User to the Profile module in Django but I get always NOT NULL constraint failed I know that last_ip should be set tonull=True and I run this commands:py .\manage.py makemigrations and py .\manage.py migrate. if you have any suggestions to save IP to the user that will be helpful for me.
Thanks in advance.
#models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(blank=True, max_length=150)
last_ip = models.GenericIPAddressField(null=True, blank=True)
avatar = ContentTypeRestrictedFileField(max_upload_size=10485760, null=True, verbose_name="",default='default.jpg', blank= True, content_types=['image/png', 'image/jpeg'])
def __str__(self):
return self.user.username
#forms.py
class UpdateUserForm(forms.ModelForm):
username = forms.CharField(max_length=150, required=True)
first_name = forms.CharField(max_length=150, required=False)
last_name = forms.CharField(max_length=150, required=False)
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ['username','first_name','last_name','email']
class UpdateAvatarBio(forms.ModelForm):
avatar = forms.ImageField()
bio = forms.CharField()
class Meta:
model = Profile
fields = ['avatar', 'last_ip', 'bio']
#views.py
def ip_client(request):
return (
x_forwarded_for.split(',')[0]
if (x_forwarded_for := request.META.get('HTTP_X_FORWARDED_FOR'))
else request.META.get('REMOTE_ADDR')
)
def profile(request):
ip = ip_client(request)
model = Profile(last_ip=ip)
model.save() # Traceback suppose here is the issue
if request.method == 'POST':
...
...
return render(request, 'profile.html', {'user_form': user_form, 'profile_form': profile_form})
You didn't add the user to Profile before saving it
def profile(request):
ip = ip_client(request)
model = Profile(last_ip=ip)
moddl.user=request.user #Add this
model.save() # Traceback suppose here is the issue
if request.method == 'POST':
...
...
return render(request, 'profile.html', {'user_form': user_form, 'profile_form': profile_form})
Edit:
Since the user is OneToOne (which means it is a the primary key), so Your code shall be like this
def profile(request):
ip = ip_client(request)
profile = Profile.objects.get(user=request.user)
profile.last_ip = ip
profile.save()
if request.method == 'POST':
...
...
return render(request, 'profile.html', {'user_form': user_form, 'profile_form': profile_form})

How to get a value of foreign key between apps of Django?

If somebody has this kind of issue, answer is below, did it :)
I have two apps (accounts and company).
accounts/models.py
class Organization(models.Model):
organization_name = models.CharField(max_length=20)
#custom user model
class NewUser(AbstractBaseUser):
which_organization = models.ForeignKey(Organization, on_delete = models.CASCADE, null=True, blank=True)
#other fields
company/models.py
from accounts import models as accounts_model
class Branch(models.Model):
branch_name = models.ForeignKey(
accounts_model.Organization, on_delete = models.CASCADE, null=True, blank=True)
#other fields
company/forms.py
from .models import Branch
class BranchForm(forms.ModelForm):
class Meta:
model = Branch
fields = '__all__'
company/views.py
from .forms import BranchForm
def some_function(request):
form = BranchForm()
if request.method == 'POST':
form = BranchForm(request.POST, request.FILES)
if form.is_valid():
form.save(commit=False)
form.branch_name = request.user.which_organization
print("User organization: ", request.user.which_organization)
form.save()
return render(request, 'company/index.html', {'form': form})
P.s. Everything works well. I am able to print the user's organization with
print("User organization : ", request.user.which_organization)
But cannot save it with
form.branch_name = request.user.which_organization
in views.py. Instead of getting exact organization name of the user, created object lists all organization names...
How to achieve it?)
Did it :D
def some_function(request):
form = BranchForm()
if request.method == 'POST':
form = BranchForm(request.POST, request.FILES)
if form.is_valid():
another_form = form.save(commit=False)
another_form.branch_name = Organisation.objects.get(id= request.user.which_organization.id )
new_form.save()
return render(request, 'company/index.html', {'form': form})
Try passing an instance of the Organisation model,
def some_function(request):
form = BranchForm()
if request.method == 'POST':
form = BranchForm(request.POST, request.FILES)
if form.is_valid():
form.save(commit=False)
organisation_instance = Organisation.objects.get(id = request.user.which_organization.id )
form.branch_name = organisation_instance
print("User organization: ", request.user.which_organization)
form.save()
return render(request, 'company/index.html', {'form': form})

RelatedObjectDoesNotExist at /profile/ User has no profile

I want to create a profile for each user but I received this error message and this my function in :
views.py :
#login_required
def profile(request):
if request.method == 'POST':
u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileUpdateForm(request.POST,
request.FILES ,instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
user_from =u_form.save()
profile_form= p_form.save(False)
user_from=profile_form
profile_form.save()
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('list')
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile) #instance=request.user.profile)
args = {}
args['u_form'] = u_form
args['p_form'] = p_form
return render(request, 'users/profile.html',args)
register user :
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
why this code don't working? I'm trying to create a registration form for users.
models.py :
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,unique=True, primary_key=True, default=None)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
def save(self):
super().save()

filter ManyToManyField(**), by user in form selection

I need to add songs to my Playlist - but I want that only the user can add your registered songs, not all songs.
I have this:
models
class Song(models.Model):
user = models.ForeignKey(User, default=1)
title=models.CharField(max_length=500)
artist = models.CharField(max_length=250)
audio = models.FileField(default='')
def __str__(self):
return self.title
class List(models.Model):
user_list = models.ForeignKey(User, default=User)
title_list=models.CharField(max_length=500)
songs = models.ManyToManyField(Song)
def __str__(self):
return self.title_list
forms
class SongForm(forms.ModelForm):
class Meta:
model = Song
fields = ['title', 'artist', 'audio']
class ListForm(forms.ModelForm):
#songs=forms.MultipleChoiceField(Song.objects.all(), widget=forms.CheckboxSelectMultiple)
#songs= forms.MultipleChoiceField( widget=forms.CheckboxSelectMultiple)
#songs=forms.ModelMultipleChoiceField(queryset=Song.objects.all(), widget=forms.CheckboxSelectMultiple) #here i dont know why the form dont save data
#I want this
songs=forms.ModelMultipleChoiceField(queryset=Song.objects.filter(user=actualuser),widget=forms.CheckboxSelectMultiple)
class Meta:
model = Lista
fields = ['title_list','songs']
#views
def new_list(request):
form=ListForm(request.POST or None, request.FILES or None)
if form.is_valid():
lista = form.save(commit=False)
lista.user_list = request.user
lista.save()
context = {
'username': request.user.username,
'lista': lista,
}
return render(request,'MyMusic/list_detail.html',context)
context={
'form':form,
'error_message': 'Error ',
}
return render(request,'MyMusic/list_form.html',context)
in forms view I need only see and I want select only my own registered songs, also I want can see a check box not the actual (widget=forms.CheckboxSelectMultiple), but actully this does not save the data.
the solution for me.
**Forms**
class ListForm(forms.ModelForm):
def __init__(self,user, *args, **kwargs):
super(ListForm, self).__init__(*args, **kwargs)
self.fields['songs'] = forms.ModelMultipleChoiceField(queryset=Song.objects.filter(user=user)
,required=False,widget=forms.CheckboxSelectMultiple)
class Meta:
model = Lista
fields = ['title_list','songs']
in views
def new_list(request):
form=ListForm(request.user,request.POST or None, request.FILES or None)
if form.is_valid():
lista = form.save(commit=False)
lista.user_list = request.user
lista.save()
lista.canciones = form.cleaned_data['songs'] # avoid conflict to save checkbox
context = {
'username': request.user.username,
'lista': lista,
}
return render(request,'MyMusic/list_detail.html',context)
context={
'form':form,
'error_message': 'Error ',
}
return render(request,'MyMusic/list_form.html',context)

Cannot submit the form with foreign key in Django

I can't submit the form with foreign key. Is it anything with foreign key?
I always redirect to the destination_list since the form is not saving.
No error is showing.
models.py
class Region(models.Model):
region = models.CharField("Region",max_length=45,blank=True)
status = models.CharField("Status",max_length=45,blank=True)
selected_region = models.CharField("Selected Region",max_length=45,blank=True)
def __str__(self):
return self.region
def get_absolute_url(self):
return reverse('update2', args=[str(self.id)])
def get_delete_url(self):
return reverse('delete2', args=[str(self.id)])
class Destination(models.Model):
region1 = models.ForeignKey(Region)
destination = models.CharField("destination",max_length=30,blank=False,unique=True)
status = models.CharField("status",max_length=30,blank=False,unique=True)
selected_destination = models.CharField("select destination",max_length=30)
def __str__(self):
return self.destination
forms.py
class DestinationForm(forms.ModelForm):
class Meta:
model = Destination
fields = [ 'region1','destination','status','selected_destination']
def __init__(self, *args, **kwargs):
super(DestinationForm, self).__init__(*args, **kwargs)
for key in self.fields:
self.fields[key].widget.attrs['class'] = 'form-control'
views.py
(I have redirect to destination_list if form is not submitted)
def add_destination(request):
form = DestinationForm()
context = {
"form": form
}
if request.method == 'POST':
form = DestinationForm(request.POST)
if form.is_valid():
form.save()
else:
return redirect(destination_list)
return render(request,'adddestination.html',context)

Resources