I am trying to create new users to the admin and to the app from NON Classe Based View in my django project, I have the model, the view and the template where I am getting the form as it goes in the next code I´m going to show..
models.py
class Users(models.Model):
# Fields
username = models.CharField(max_length=255, blank=True, null=True)
password = models.CharField(max_length=12, blank=True, null=True)
organization_id = models.ForeignKey('ip_cam.Organizations', editable=True, null=True, blank=True)
slug = extension_fields.AutoSlugField(populate_from='created', blank=True)
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
# Relationship Fields
user_id = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True)
class Meta:
ordering = ('-created',)
def __str__(self):
return u'%s' % self.user_id
def get_absolute_url(self):
return reverse('ip_cam_users_detail', args=(self.slug,))
def get_update_url(self):
return reverse('ip_cam_users_update', args=(self.slug,))
def __unicode__(self): # __str__
self.organization_id=self.request.POST.get('organization_id')
return unicode(self.user_id, self.organization_id)
# This overrides the standard save method for a user, creating a new user in the admin and getting it to the template at the same time
def save(self, *args, **kwargs):
self.password = make_password(self.password)
self.user_id, created = User.objects.get_or_create(username=self.username, password=self.password, is_staff=True)
self.user_id.groups.add(Group.objects.get(name='admin'))
self.id = self.user_id.id
super(Users, self).save(*args, **kwargs)
views.py
def UsersCreate(request):
model = Users
var = {}
var = user_group_validation(request)
userInc = Users.objects.get(id=request.user.id).organization_id.pk
request.session['userInc'] = userInc
if var['group'] == 'superuser':
object_list = Users.objects.all()
organization = Organizations.objects.all()
roles_choice = DefaultLandingPage.objects.all()
if var['group'] == 'admin' or var['group'] == 'user':
object_list = Users.objects.filter(organization_id=request.session['userInc'])
organization = Organizations.objects.filter(id=request.session['userInc'])
roles_choice = DefaultLandingPage.objects.exclude(role=1)
url = request.session['url']
tpl = var['tpl']
role = var['group']
organization_inc = Organizations.objects.filter(id=request.session['userInc'])
template = get_template(app+u'/users_form.html')
return HttpResponse(template.render(locals()))
the problem in here is that the save is not working when trying to override it, user is not created at all... can you please help me to see what am I doing wrong this time ? thanks in advance.
If you are not using the generic django class based views, you will have to implement the request's POST and GET functionality yourself. The easiest is to create a form from your user model and handle the request based on whether it's a POST request type or not.
Try this:
forms.py (https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/)
from django.forms import ModelForm
from .models import User
class UserForm(ModelForm):
class Meta:
model = Users
fields = ['username', 'organization_id']
views.py
from .models import User
from .forms import UserForm
def UsersCreate(request):
# This function can hadle both the retrieval of the view, as well as the submission of the form on the view.
if request.method == 'POST':
form = UserForm(request.POST, request.FILES)
if form.is_valid():
form.save() # This will save the user.
# Add the user's role in the User Role table below?
#
else:
# The form should be passed through. This will be processed when the form is submitted on client side via this functions "if request.method == 'POST'" branch.
form = UserForm()
var = user_group_validation(request)
userInc = Users.objects.get(id=request.user.id).organization_id.pk
request.session['userInc'] = userInc
if var['group'] == 'superuser':
object_list = Users.objects.all()
organization = Organizations.objects.all()
roles_choice = DefaultLandingPage.objects.all()
if var['group'] == 'admin' or var['group'] == 'user':
object_list = Users.objects.filter(organization_id=request.session['userInc'])
organization = Organizations.objects.filter(id=request.session['userInc'])
# The line below will ensure that the the dropdown values generated from the template will be filtered by the 'request.session['userInc']'
form.organisation_id.queryset = organization
roles_choice = DefaultLandingPage.objects.exclude(role=1)
url = request.session['url']
tpl = var['tpl']
role = var['group']
organization_inc = Organizations.objects.filter(id=request.session['userInc'])
template = get_template(app+u'/users_form.html')
return HttpResponse(template.render(locals()))
In your app+u'/users_form.html' file, you can access the UserForm fields as follows:
<!-- inside your <form> tag add: -->>
{{ form.username }}
{{ form.organisation_id }}
I haven't tested this code but this should get you on the right track.
Related
I'm trying to save and retrive the data owned by the user.
I mean, in one Sqlite3 DB I store the tables for all users but each one has their one data store in it, how can I give each one their own data.
this are my models, view and form
MODEL.PY
class Cuentas (models.Model):
rubro_cta = models.ForeignKey(TipoC, on_delete=models.CASCADE, verbose_name = u'Tipo')
sub_rubro_cta = models.ForeignKey(Sub_rubro, on_delete=models.CASCADE, verbose_name = u'Sub Rubro')
titulo_cuenta = models.CharField(max_length=50)
detalle_cuenta = models.CharField(max_length=60)
importe_cuenta = models.FloatField()
def save(self, *args, **kwargs):
self.importe_cuenta = round(self.importe_cuenta, 2)
super(Cuentas, self).save(*args, **kwargs)
def __str__(self):
return self.detalle_cuenta
FORMS.PY
class CuentasForm (forms.ModelForm):
class Meta:
model = Cuentas
fields = ['rubro_cta', 'sub_rubro_cta', 'detalle_cuenta', 'importe_cuenta']
labels = {
'rubro_cta': _('Cuenta'),
'sub_rubro_cta': _('Tipo'),
'detalle_cuenta': _('Detalle'),
'importe_cuenta': _('Importe'),
}
VIEWS.PY
#login_required
def carga (request):
if request.method == 'POST':
form = CuentasForm(request.POST)
if form.is_valid:
form.save()
return redirect('balance')
else:
form = CuentasForm()
return render (request, "ProyetoWebApp/carga.html",{"form": form})
you have to add a foreign key field to user in your Cuentas class:
class Cuentas (models.Model):
user = models.ForeignKey(User, models.CASCADE)
...
in your view add this code for GET method:
info = None
if request.method == 'GET':
info = Cuentas.objects.get(user=request.user)
return render (request, "ProyetoWebApp/carga.html",{"form": form, "info":info})
I'm trying to display a form (ModelForm) with a select field filtered by currently logged in user. The select field in this case contains a list of categories. I want to display only the categories which "belong" to the currently logged in user. The category field is a foreign key to the IngredienceCategory model.
Here is what I've come up with so far but it's giving me an error (unexpected keyword queryset). Any ideas what I'm doing wrong?
# models.py
class IngredienceCategory(models.Model):
name = models.CharField(max_length=30)
user = models.ForeignKey(User, null=True, blank=True)
class Meta:
verbose_name_plural = "Ingredience Categories"
def __unicode__(self):
return self.name
class Ingredience(models.Model):
name = models.CharField(max_length=30)
user = models.ForeignKey(User, null=True, blank=True)
category = models.ForeignKey(IngredienceCategory, null=True, blank=True)
class Meta:
verbose_name_plural = "Ingredients"
def __unicode__(self):
return self.name
class IngredienceForm(ModelForm):
class Meta:
model = Ingredience
fields = ('name', 'category')
# views.py
def home(request):
if request.user.is_authenticated():
username = request.user.username
email = request.user.email
foods = Food.objects.filter(user=request.user).order_by('name')
ingredients = Ingredience.objects.filter(user=request.user).order_by('name')
ingrcat = IngredienceCategory.objects.filter(user=request.user)
if request.method == 'POST':
form = IngredienceForm(request.POST)
if form.is_valid():
# Create an instance of Ingredience without saving to the database
ingredience = form.save(commit=False)
ingredience.user = request.user
ingredience.save()
else:
# How to display form with 'category' select list filtered by current user?
form = IngredienceForm(queryset=IngredienceCategory.objects.filter(user=request.user))
context = {}
for i in ingredients:
context[i.category.name.lower()] = context.get(i.category.name.lower(), []) + [i]
context2 = {'username': username, 'email': email, 'foods': foods, 'ingrcat': ingrcat, 'form': form,}
context = dict(context.items() + context2.items())
else:
context = {}
return render_to_response('home.html', context, context_instance=RequestContext(request))
That's happening because ModelForm does not take a queryset keyword.
You can probably achieve this by setting the queryset on the view:
form = IngredienceForm()
form.fields["category"].queryset =
IngredienceCategory.objects.filter(user=request.user)
See related question here.
Here i have another suggestion to solve the problem. You can pass request object in your form object inside view.
In view.py just pass the request object.
form = IngredienceForm(request)
In your forms.py __init__ function also add request object
from models import IngredienceCategory as IC
class IngredienceForm(ModelForm):
class Meta:
model = Ingredience
fields = ('name', 'category')
def __init__(self, request, *args, **kwargs):
super(IngredienceForm, self).__init__(*args, **kwargs)
self.fields['name'].queryset = IC.objects.filter(user=request.user)
This filter always will be applied whenever you initialize your form .
I've created a Django view that does 2 things:
Create a new account
Modify a account
Works:
Creating new account and submitting the HTML form data to the database. Also works: showing a prefilled HTML form if user wants to modify an account with the account data that is known in the database.
Doesnt work:
When the user submits his/her form to update an account (user modified the info in the form), nothing is updated in the database.
I know how to update one single static value in the database like so:
a = accounts.objects.filter(pk=account_id).update(name='static value here')
but I don't know how to update the database with all the form data that the user submits when using Django Modelforms. Does anyone knows how to update the database with the submitted form data?
Code
#login_required(login_url='/dashboard/')
def dashboard_accounts_new_modify(request, account_id=None):
if request.method == 'POST':
# POST DETECTED
form = MyModelForm(request.POST, request.FILES)
if account_id:
# POST DETECTED
# ACCOUNT ID FOUND
# USER WANTS TO MODIFY A ACCOUNT
# WITH THIS QUERY I CAN UPDATE 1 STATIC VALUE IN THE DATABASE
# HOW DO I UPDATE THE VALUES FROM THE FORM IN THE DATABASE?? :(
a = accounts.objects.filter(pk=account_id).update(name='static value here')
return HttpResponseRedirect('/dashboard/accounts/')
else:
# POST DETECTED
# ACCOUNT ID NOT FOUND
# USER WANTS TO CREATE A NEW ACCOUNT
if form.is_valid():
if request.POST.get("name").lower() == 'new':
raise Http404("New account name may not be named NEW.")
# DATAHASE QUERY: ADD NEW ACCOUNT TO DATABASE
form.save()
# REDIRECT
return HttpResponseRedirect('/dashboard/accounts/')
elif account_id:
# NO POST DETECTED
# ACCOUNT ID FOUND
# PREFILL FORM WITH DATA
try:
from django.forms.models import model_to_dict
a = accounts.objects.get(pk=account_id)
form = MyModelForm(initial=model_to_dict(a))
except:
raise Http404("Account not found.")
else:
# NO POST DETECTED
# MODIFICATION IS NOT DETECTED
# LOAD EMPTY FORM
form = MyModelForm()
return render(request, 'backend/base_accounts_new.html', {'Title': 'Accounts', 'form' : form})
Model
# Clientdatabase
class accounts(models.Model):
name = models.CharField(max_length=200)
url = models.CharField(max_length=200)
website_title = models.CharField(max_length=200)
website_h1_text = models.CharField(max_length=200)
website_h2_text = models.CharField(max_length=200)
website_search_text = models.CharField(max_length=200)
website_font = models.CharField(max_length=200)
website_footer_left = models.CharField(max_length=600)
website_footer_right = models.CharField(max_length=600)
website_color_code_search_button = models.CharField(max_length=200)
website_color_code_banner = models.CharField(max_length=200)
website_logo_height_pixels = models.PositiveIntegerField()
website_logo_width_pixels = models.PositiveIntegerField()
filepath_favicon = models.FileField()
filepath_logo_vector = models.FileField()
filepath_logo_normal = models.FileField()
filepath_background_1 = models.FileField()
filepath_background_2 = models.FileField(blank=True, null=True)
filepath_background_3 = models.FileField(blank=True, null=True)
filepath_background_4 = models.FileField(blank=True, null=True)
setting_background_1_active = models.BooleanField()
setting_background_2_active = models.BooleanField()
setting_background_3_active = models.BooleanField()
setting_background_4_active = models.BooleanField()
def __str__(self):
return self.name
class AccountsForm(ModelForm):
class Meta:
model = accounts
fields = '__all__'
You can do like:
from django.shortcuts import get_object_or_404
if request.method == 'POST':
if account_id::
account = get_object_or_404(accounts, pk=account_id)
form = MyModelForm(request.POST,request.FILES, instance=account)
if form.is_valid():
...
form.save()
return HttpResponseRedirect('/dashboard/accounts/')
else:
form = MyModelForm(request.POST, request.FILES)
if form.is_valid():
if request.POST.get("name").lower() == 'new':
raise Http404("New account name may not be named NEW.")
form.save()
Learn more about forms here
I'm trying to display a form (ModelForm) with a select field filtered by currently logged in user. The select field in this case contains a list of categories. I want to display only the categories which "belong" to the currently logged in user. The category field is a foreign key to the IngredienceCategory model.
Here is what I've come up with so far but it's giving me an error (unexpected keyword queryset). Any ideas what I'm doing wrong?
# models.py
class IngredienceCategory(models.Model):
name = models.CharField(max_length=30)
user = models.ForeignKey(User, null=True, blank=True)
class Meta:
verbose_name_plural = "Ingredience Categories"
def __unicode__(self):
return self.name
class Ingredience(models.Model):
name = models.CharField(max_length=30)
user = models.ForeignKey(User, null=True, blank=True)
category = models.ForeignKey(IngredienceCategory, null=True, blank=True)
class Meta:
verbose_name_plural = "Ingredients"
def __unicode__(self):
return self.name
class IngredienceForm(ModelForm):
class Meta:
model = Ingredience
fields = ('name', 'category')
# views.py
def home(request):
if request.user.is_authenticated():
username = request.user.username
email = request.user.email
foods = Food.objects.filter(user=request.user).order_by('name')
ingredients = Ingredience.objects.filter(user=request.user).order_by('name')
ingrcat = IngredienceCategory.objects.filter(user=request.user)
if request.method == 'POST':
form = IngredienceForm(request.POST)
if form.is_valid():
# Create an instance of Ingredience without saving to the database
ingredience = form.save(commit=False)
ingredience.user = request.user
ingredience.save()
else:
# How to display form with 'category' select list filtered by current user?
form = IngredienceForm(queryset=IngredienceCategory.objects.filter(user=request.user))
context = {}
for i in ingredients:
context[i.category.name.lower()] = context.get(i.category.name.lower(), []) + [i]
context2 = {'username': username, 'email': email, 'foods': foods, 'ingrcat': ingrcat, 'form': form,}
context = dict(context.items() + context2.items())
else:
context = {}
return render_to_response('home.html', context, context_instance=RequestContext(request))
That's happening because ModelForm does not take a queryset keyword.
You can probably achieve this by setting the queryset on the view:
form = IngredienceForm()
form.fields["category"].queryset =
IngredienceCategory.objects.filter(user=request.user)
See related question here.
Here i have another suggestion to solve the problem. You can pass request object in your form object inside view.
In view.py just pass the request object.
form = IngredienceForm(request)
In your forms.py __init__ function also add request object
from models import IngredienceCategory as IC
class IngredienceForm(ModelForm):
class Meta:
model = Ingredience
fields = ('name', 'category')
def __init__(self, request, *args, **kwargs):
super(IngredienceForm, self).__init__(*args, **kwargs)
self.fields['name'].queryset = IC.objects.filter(user=request.user)
This filter always will be applied whenever you initialize your form .
I have a form from my model that needs to be validated and saved making use of ManyToMany Fields.
Everytime I try and save it, I get thrown back to the page, just saying this field is required
My models.py
class HuntingReport(models.Model):
user = models.ForeignKey(User, related_name='User')
outfitter = models.ForeignKey(User, related_name='Outfitter', null=True, blank=True)
date_travel_started = models.DateField(blank=True, null=True)
date_travel_ended = models.DateField(null=True, blank=True)
title = models.CharField(max_length=50)
report = models.TextField()
wish_list = models.ManyToManyField(Specie)
bag_list = models.ManyToManyField(Trophies)
def __unicode__(self):
return self.title
My forms.py looks as follows
class HuntingReportForm(ModelForm):
date_travel_started = forms.DateField(widget=extras.SelectDateWidget(years=range(1970,2010)))
date_travel_ended = forms.DateField(widget=extras.SelectDateWidget(years=range(1970,2010)))
wish_list = forms.ModelMultipleChoiceField(queryset=Specie.objects.all(), widget=FilteredSelectMultiple("verbose name", is_stacked=False))
bag_list = forms.ModelMultipleChoiceField(queryset=Trophies.objects.all(), widget=FilteredSelectMultiple("verbose name", is_stacked=False))
class Meta:
model = HuntingReport
exclude = ['user']
def __init__(self, user, *args, **kwargs):
super(HuntingReportForm, self).__init__(*args, **kwargs)
users = User.objects.filter(userprofile__outfitter=True)
self.fields['outfitter'].choices = [('', '')] + [(user.pk, user.get_full_name()) for user in users]
my views.py
def create(request, template_name='reports/new.html'):
if request.method == 'POST':
form = HuntingReportForm(request.POST, request.FILES)
if form.is_valid():
newform = form.save(commit=False)
newform.user = request.user
newform.save_m2m()
return HttpResponseRedirect('/hunting-reports/')
else:
form = HuntingReportForm(request.user)
context = { 'form':form, }
return render_to_response(template_name, context,
context_instance=RequestContext(request))
Did you try passing blank=True for model field's constructor, or required=False for the ModelMultipleChoiceField's constructor?
I know that blank=True solves the problem for the form in the admin panel, but I don't know how it gets mapped to the ModelForm's fields. I'm assuming that it gets mapped to required property.