I am working on a Django-Tenant (Multi-Tenant) application. I am writing the script to create the subdomain. I am trying to get it to where created_by is set to the current users id that is logged in. How can I get current user ID to populate the created_by field?
views.py
class CreatePortal(View):
def get(self, request):
form = CreatePortalForm()
return render(request, "registration/create_portal.html", {"form": form})
def post(self, request):
form = CreatePortalForm(request.POST)
if form.is_valid():
getDomain = form.cleaned_data.get('name')
instance = form.save(commit=False)
tenant = Client(schema_name=getDomain, name=getDomain, created_by=**[NEED USER ID HERE]**)
tenant.save()
domain = Domain()
domain.domain = (getDomain + ".example.com:8000")
domain.tenant = tenant
domain.is_primary
domain.save()
with schema_context(tenant.schema_name):
instance.save()
redirect = 'http://' + getDomain + '.example.com:8000'
return HttpResponseRedirect(redirect)
return render(request, "registraton/create_portal.html", {"form": form})
forms.py
class CreatePortalForm(forms.ModelForm):
class Meta:
model = Client
fields = ["name"]
models.py
This is the line that I am working with models.py
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
I also get an error if it is not User type and if I do not pass an actual number for id, Field 'id' expected a number but got datetime.datetime
I have tried this as well:
user = request.user.id
tenant = Client(schema_name=getDomain, name=getDomain, created_by=user)
but then get this error:
Cannot assign "1": "Client.created_by" must be a "User" instance.
I am not sure how to pass the current logged in Users ID to populate the created_by form field. Any and all help is appreciated. I am still learning Django.
I am trying to associate the user with the post. I have two models students is for user and sublists is for user posts with a foreign key(author). I am using MySQL database and using forms to store data into them. when my form.author execute in my HTML file it gives me a list of ids for all users in the databse but I am already logged in and i want to post as the logged in user without choosing. If remove it says my form is not valid which make sense since im not inputing for form.author.Since I'm using MySQL, I'm not using the built-in User authentication method, but instead comparing both email and password with the login form input. Spend too much time on this but hard to get around with this one. Any help would be appreciated
my views.py look like this
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
try:
form.save()
messages.success(request, ' Subscirption Saved')
name = sublist.objects.get(name=name)
return render (request, 'subscrap/main.html', {'sublist': name})
except:
pass
else:
messages.success(request, 'Error')
pass
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
#login_required(login_url='login')
#cache_control(no_cache=True, must_revalidate=True, no_store=True)
def main(request):
return render(request, 'subscrap/main.html')
def mod(request):
student = students.objects.all()
return render(request, 'subscrap/mod.html' , {'students': student})
My Models.py
class students(models.Model):
fname = models.CharField(max_length=50)
lname = models.CharField(max_length=50)
password = models.CharField(max_length = 50 , null = True)
passwordrepeat = models.CharField(max_length = 50, null = True)
email = models.EmailField(max_length=150)
class Meta:
db_table = "students"
class sublist(models.Model):
author = models.ForeignKey(students, related_name='sublist' ,on_delete=models.CASCADE)
name = models.CharField(max_length=150)
cost = models.IntegerField(default = 0)
renewalcycle = models.IntegerField(default = 0)
class Meta:
db_table = "sublist"
Since I'm using forms here's my forms.py
lass StudentForm(forms.ModelForm):
class Meta:
model = students
fields = "__all__"
class Studentlogin(forms.Form):
email = forms.EmailField(max_length=150)
password = forms.CharField(max_length = 50, widget=forms.PasswordInput)
class Sublist(forms.ModelForm):
class Meta:
model = sublist
fields = "__all__"
Exclude the Author from the Sublist form:
class Sublist(forms.ModelForm):
class Meta:
model = sublist
exclude = ['author']
In the addnew method, you associate the .instance.author with the request.user:
#login_required(login_url='login')
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
form.instance.author = request.user
form.save()
messages.success(request, ' Subscirption Saved')
return redirect('some_view')
else:
messages.error(request, 'Error')
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
Note: Models in Django are written in PascalCase, not snake_case,
so you might want to rename the model from sublist to Sublist.
Note: Usually a Form or a ModelForm ends with a …Form suffix,
to avoid collisions with the name of the model, and to make it clear that we are
working with a form. Therefore it might be better to use SublistForm instead of
Sublist.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the students directly. For more information you can see the referencing the User model section of the documentation.
I have a model
class someModel(models.Model):
.....
.....
user = models.OneToOneField(User, on_delete=models.CASCADE)
#User is the field that I need from the form
.....
.....
Here I have fields that have to be filled and the user field that is connected to the users table
In my forms
class someForm(forms.ModelForm):
class Meta:
model = someModel
fields = [....., 'user']
widgets = { .... }
I want to pass the user from my view but I don't know how to do that and I cant find it online. Form fails because the user is not passed.
#login_required
def someView(request):
organisator= request.user
if request.method == "POST":
cl_form = SomeModel(data=request.POST, initial={'user': organisator})
if cl_form.is_valid():
cl_form.save(commit=True)
else:
print(cl_form.errors)
return HttpResponseRedirect(reverse('someviewfromurls'))
else:
cl_form = someForm(initial={'user':organisator})
return render(request, 'somefile.html', context=
{"cl_form": cl_form})
You can try like this:
if cl_form.is_valid():
instance = cl_form.save(commit=False)
instance.user = request.user
instance.save()
I have a form in my application which has a hidden form field, the value of which I want to set in my corresponding view after submitting the form.
forms.py
class EvangelizedForm(forms.ModelForm):
first_name = forms.CharField(help_text="First Name")
last_name = forms.CharField(help_text="Last Name")
email = forms.CharField(help_text="Email ID")
mobile_no = forms.CharField(help_text="Mobile number")
twitter_url = forms.CharField(help_text="Twitter URL")
twitter_followers = forms.CharField(widget = forms.HiddenInput()) #Hidden form field
class Meta:
model = Evangelized
fields = ('first_name','last_name', 'twitter_url', 'email', 'mobile_no')
models.py
class Evangelized(models.Model):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField()
mobile_no = models.CharField(unique=True, max_length = 10, validators=[RegexValidator(regex='^\w{10}$', message='Mobile number should be strictly of 10 digits.')])
twitter_url = models.CharField(unique=True, max_length=128)
twitter_followers = models.CharField(max_length = 128)
views.py
def fillform(request):
follower_count = '250'
if request.method == 'POST':
form = EvangelizedForm(request.POST)
if form.is_valid():
form.fields['twitter_followers'] = follower_count
form.save(commit=True)
return index(request)
else:
form.errors
else:
#form = EvangelizedForm()
if request.user.is_authenticated():
form = EvangelizedForm(initial={'first_name': request.user.first_name,
'twitter_url': 'https://twitter.com/' + request.user.username,
'last_name': request.user.last_name})
else:
form = EvangelizedForm()
context = RequestContext(request,
{'request': request,
'user': request.user, 'form':form})
#return render(request, 'rango/fillform.html', {'form': form, 'context_instance':context})
return render_to_response('rango/fillform.html',
context_instance=context)
Basically, I'm trying to set the value of twitter_followers (which is a hidden form field in forms.py) in my index view, by:
follower_count = '250'
..
..
form.fields['twitter_followers'] = follower_count
By doing this, I'm expecting the value of 'twitter_followers' in the database after submitting the form to be '250'. However, this approach doesn't seem to be working.
What's the right way to set values to certain attributes in the database manually using views?
You need to set it on the model instance, which is the result of form.save. That's the main reason for the commit argument in the first place.
if form.is_valid()
obj = form.save(commit=True)
obj.twitter_follower = follower_count
obj.save()
You can override the save method of the form, with something like this:
def save(self, *args, **kwargs)
twitter_followers = kwargs.pop('twitter_followers', 0)
self.instance.twitter_followers = twitter_followers
super(Evangelized, self).save(args, kwargs)
And then in the view just have to call in this way:
form.save(twitter_followers=250)
I've been struggling with this all week long, and I need to put it to rest once and for all. This might look like a lot of code, but at the core is a simple conceptual question.
I have a model, UserProfile, that has the following fields:
user = models.OneToOneField(User)
weekOne = models.OneToOneField(WeekOne)
weekTwo = models.OneToOneField(WeekTwo)
WeekOne and WeekTwo are both models with their own unique fields (models.Model) that inherit from a custom class called Week. Week just has a few custom functions to save some re-typing of methods for each week and the following code to make it an abstract class:
class Meta:
abstract = True
Basically, I want every user to have a unique weekOne and weekTwo (and beyond) field that has custom fields with values that are unique to the user.
When I first create a user (i.e., when they sign up), I use the following code in views.py:
def signup(request):
user_form = UserCreateForm(data=request.POST)
if request.method == 'POST':
if user_form.is_valid():
username = user_form.clean_username()
password = user_form.clean_password2()
user_form.save()
user = authenticate(username=username, password=password)
login(request, user)
return redirect('/')
else:
return index(request, user_form=user_form)
return redirect('/')
Basic form signup stuff, everything has always worked fine here.
Now, here's where things get dicey. I have a view for weekOne that makes sure a user's profile has been created and creates one if not, the code for which is as follows:
#login_required
def workout1(request):
template = "workout1.html"
weekOne = WeekOne()
weekOne.save()
user, created = UserProfile.objects.get_or_create(user=request.user,
defaults = {'weekOne': weekOne})
name = weekOne.__unicode__()
if created:
context = {'user': user}
return render(request, template, context)
# Grab already existing User Profile
weekOne.delete() # Was never used
context = {'user': user, 'name': name}
return render(request, template, context)
Okay. So that's cool. But when I try to go to the page for week one, I get the following error:
workout_game_app_userprofile.weekTwo_id may not be NULL
This is where I'm lost. Should I be initializing every single week variable for every single week view? I.e., for the week one view, should I be doing code like this:
weekOne = WeekOne()
weekTwo = WeekTwo()
weekThree = WeekThree()
etc.? This seems absurdly repetitive if I have to do it for all 12 weeks I'm planning on implementing.
Btw, my models were functioning perfectly well before I implemented the second week.
Also, is OneToOne the right kind of key to use? I want to do things like access user.weekOne.item1, user.weekOne.item2, etc. and change and save their values only for that user.
UPDATE: For Sidharth Shah, here's the rest of the code from my views and models:
views.py:
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.models import User
from workout_game_app.forms import AuthenticateForm, UserCreateForm
from workout_game_app.models import WeekOne, WeekTwo, UserProfile
from django.http import Http404, HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_exempt
from django.core import serializers
import simplejson
def index(request, auth_form=None, user_form=None):
if request.user.is_authenticated():
user = request.user
name = "Missions Overview"
context = {'user': user, 'name': name}
template = 'workouts.html'
return render(request, template, context)
else:
auth_form = auth_form or AuthenticateForm()
user_form = user_form or UserCreateForm()
template = 'index.html'
context = {'auth_form': auth_form, 'user_form': user_form}
return render(request, template, context)
def login_view(request):
if request.method == 'POST':
form = AuthenticateForm(data=request.POST)
if form.is_valid():
login(request, form.get_user())
return redirect('/')
else:
return index(request, auth_form=form)
return redirect('/')
def signup(request):
user_form = UserCreateForm(data=request.POST)
if request.method == 'POST':
if user_form.is_valid():
username = user_form.clean_username()
password = user_form.clean_password2()
user_form.save()
user = authenticate(username=username, password=password)
login(request, user)
return redirect('/')
else:
return index(request, user_form=user_form)
return redirect('/')
#login_required
def submitWorkout1(request):
if request.method == 'POST':
exercise = request.POST['exercise']
try:
amount = request.POST['amount']
except KeyError: # No amount field on form
amount = ""
user = UserProfile.objects.get(user=request.user)
week = user.weekOne
exercise, amount, exerciseComplete, allComplete = user.updateExercise(week, exercise, amount)
data = simplejson.dumps({
'result': 'success',
'exercise': exercise,
'amount': amount,
'exerciseComplete': exerciseComplete,
'allComplete': allComplete
}, indent=4)
return HttpResponse(data)
#login_required
def workout2(request):
template = "workout2.html"
weekTwo = WeekTwo()
weekTwo.save()
user, created = UserProfile.objects.get_or_create(user=request.user,
defaults = {'weekTwo': weekTwo})
name = weekTwo.__unicode__()
if created:
context = {'user': user}
return render(request, template, context)
# Grab already existing User Profile
weekTwo.delete() # Was never used
context = {'user': user, 'name': name}
return render(request, template, context)
#login_required
def submitWorkout2(request):
if request.method == 'POST':
exercise = request.POST['exercise']
try:
amount = request.POST['amount']
except KeyError: # No amount field on form
amount = ""
user = UserProfile.objects.get(user=request.user)
week = user.weekTwo
exercise, amount, exerciseComplete, allComplete = user.updateExercise(week, exercise, amount)
data = simplejson.dumps({
'result': 'success',
'exercise': exercise,
'amount': amount,
'exerciseComplete': exerciseComplete,
'allComplete': allComplete
}, indent=4)
return HttpResponse(data)
and models.py:
from django.db import models
from django.contrib.auth.models import User
class Week(models.Model):
# List of exercises by name for the week
exercises = []
# Week name in unicode
name = u''
# Running count of benchmarks met.
completeCount = models.PositiveSmallIntegerField(default=0)
# Set to true if benchmarks reached.
weekComplete = models.BooleanField(default=False)
# A bunch of methods
class WeekOne(Week):
name = u'Mission One'
exercises = ['squats', 'lunges', 'stairDaysCount', 'skipStairs']
# Required benchmarks for given exercises
squatBenchmark = 1000
lungeBenchmark = 250
stairDaysCountBenchmark = 3
totalGoals = 4
squats = models.PositiveIntegerField(default=0)
lunges = models.PositiveIntegerField(default=0)
skipStairs = models.BooleanField(default=False)
stairDaysCount = models.PositiveSmallIntegerField(default=0)
# A bunch of methods
class WeekTwo(Week):
name = u'Mission Two'
exercises = ['up3Levels', 'noHands', 'treadmill', 'vagMachine', 'extendedStairs']
totalGoals = 5
up3Levels = models.BooleanField(default=False)
noHands = models.BooleanField(default=False)
treadmill = models.BooleanField(default=False)
vagMachine = models.BooleanField(default=False)
extendedStairs = models.BooleanField(default=False)
# A bunch of methods
class UserProfile(models.Model):
user = models.OneToOneField(User)
weekOne = models.OneToOneField(WeekOne, null=True, default=None)
weekTwo = models.OneToOneField(WeekTwo, null=True, default=None)
# Some methods
and, though it works fine, my forms.py for good measure:
from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
from django.contrib.auth.models import User
from django import forms
from django.utils.html import strip_tags
class UserCreateForm(UserCreationForm):
username = forms.CharField(required=True,
widget = forms.widgets.TextInput(attrs={'placeholder': 'Username'}))
password1 = forms.CharField(required=True,
widget = forms.widgets.PasswordInput(attrs={'placeholder': 'Password'}))
password2 = forms.CharField(required=True,
widget = forms.widgets.PasswordInput(attrs={'placeholder': 'Password'}))
def is_valid(self):
form = super(UserCreateForm, self).is_valid()
for f, error in self.errors.iteritems():
if f != '__all_':
self.fields[f].widget.attrs.update({'class':'error', 'value':strip_tags(error)})
return form
class Meta:
fields = ['username', 'password1', 'password2']
model = User
class AuthenticateForm(AuthenticationForm):
username = forms.CharField(
widget = forms.widgets.TextInput(attrs={'placeholder':'Username'}))
password2 = forms.CharField(
widget = forms.widgets.PasswordInput(attrs={'placeholder': 'Password'}))
You might want to have following model
user = models.OneToOneField(User)
weekOne = models.OneToOneField(WeekOne, null=True, default=None)
weekTwo = models.OneToOneField(WeekTwo, null=True, default=None)
Try that out, it should work. Looking at the code above you're defining fields weekOne, weekTwo etc. What I am not sure of is if you're assigning all necessary fields weekOne object while creating it.