jahantaila
jahantaila

Reputation: 908

Saving username to model in Django

I am creating a donation app that allows donors to create listings. This data is stored in a Django Model and is going to be displayed on a page. I want to save the user's username to the Django model and display it on the page. My code is down below


Models.py

class Donation(models.Model):
  title = models.CharField(max_length=30)
  phonenumber = models.CharField(max_length=12)
  category = models.CharField(max_length=20)
  image = models.CharField(max_length=1000000)
  deliveryorpickup = models.CharField(max_length=8)
  description = models.TextField()

Views.py

from django.contrib.auth.models import User
from django.http.request import RAISE_ERROR
from django.http.response import HttpResponseRedirect
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.forms import forms, inlineformset_factory
from django.contrib.auth.forms import UserCreationForm, UsernameField
from .forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from home.models  import Donation 

# Create your views here.

def index(request,*args, **kwargs):
  return render(request, "index.html", {} )



@login_required(login_url='/login/')
def dashboard(request,*args, **kwargs):
  return render(request, "dashboard.html", {} )

def register(request, ):
    if request.user.is_authenticated:
        return redirect('/dashboard/')
    else: 
        form = CreateUserForm()
        if request.method == "POST":
            form = CreateUserForm(request.POST)
            if form.is_valid():
                form.save()
                username = form.cleaned_data.get('username')
                messages.success(request, f'Your account has been successfully created, {username} ')
                return redirect('loginpage')
        context = {'form': form}
        return render(request, "register.html",  context )



def loginpage(request):
    if request.user.is_authenticated:
        return redirect('/dashboard/')
    else:
        if request.method == 'POST':
            username = request.POST.get('username')
            password =request.POST.get('password')

            user = authenticate(request, username=username, password=password)

            if user is not None:
                login(request, user)
                return redirect('/dashboard')
            else:
        
                messages.error(request, 'Username OR password is incorrect')

        context = {}
        return render(request, 'login.html', context)

def logoutuser(request):
    logout(request)
    return HttpResponseRedirect('/login/')

@login_required(login_url='/login/')
def donate(request):
    if request.method == "POST":
        title = request.POST['donationtitle']
        phonenumber = request.POST['phonenumber']
        category = request.POST['category']
        image = request.POST['imagelink']
        deliveryorpickup = request.POST['deliveryorpickup']
        description = request.POST['description']
        ins = Donation(title = title, phonenumber = phonenumber, category = category, image = image, deliveryorpickup = deliveryorpickup, description = description )
        ins.save()
    return render(request,'donate.html')

Forms.py (This is where the user is created)

class CreateUserForm(UserCreationForm):
  username = forms.CharField(required=True, max_length=30, ) 
  email = forms.EmailField(required=True)
  first_name = forms.CharField(required=True, max_length=50)
  last_name = forms.CharField(required=True, max_length=50)
  

  
  class Meta:
    model = User
    fields = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2',]
  #function to display errors
  def clean(self):
          cleaned_data=super().clean()
          password1 = self.cleaned_data.get('password1')
          password2 = self.cleaned_data.get('password2')

          if User.objects.filter(username=cleaned_data["username"]).exists():
            raise ValidationError("This username is taken, please try another one")

          elif password1 != password2:
            raise forms.ValidationError("2 password fields do not match")

          elif len(password1) < 8 or len(password2) < 8:
            raise forms.ValidationError("Passwords must be at least 8 characters long")

Upvotes: 0

Views: 2518

Answers (1)

damon
damon

Reputation: 15128

To associate the user with the Donation model, you should first add a ForeignKey field to the model class:

from django.conf import settings

class Donation(models.Model):
    ...  # your other donation fields
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
    )

Once you've made this change, and run the migrations, in your views.py you'll pass the currently signed in user to the Donation model creation:

@login_required(login_url='/login/')
def donate(request):
    if request.method == "POST":
        ins = Donation(
            title=request.POST["title"],
            ...  # all of the other fields

            user=request.user,  # 👈 This adds the user
        )
        ins.save()
    return render(request,'donate.html')

Notes

Using settings.AUTH_USER_MODEL allows your class to use a custom user model, or django's default user model, based on your project's settings.

To understand what on_delete=models.CASCADE does, you should read django's documentation about it.

Also, instead of manually passing all of the request.POST[...] values to the Donation model, I recommend that you use a ModelForm. It will handle errors and validation for you, as well as generate the HTML displayed in the template. Using a model form here would make your view code change to this:

from django.forms import ModelForm

class DonationForm(ModelForm):
    class Meta:
        model = Donation
        exclude = ["user"]

@login_required(login_url="/login/")
def donate(request):
    if request.method == "POST":
        form = DonationForm(request.POST)
        if form.is_valid():
            donation = form.save(commit=False)
            donation.user = request.user
            donation.save()
            # Use a redirect to prevent duplicate submissions
            # https://docs.djangoproject.com/en/3.2/topics/http/shortcuts/#redirect
            return redirect(request, ...)
    else:
        form = DonationForm()
    return render(request, "donate.html", {"form": form})

Upvotes: 2

Related Questions