I'm using Pinax to create a new project. For this project I needed to create a new app 'Business' which is much like Profiles but they wanted to keep everything seperate for Businesses.
I'm trying to have the admin be able to change the logo or "avatar" for the business profile. Im using the ImageModel class from Photologue to control the image upload, etc but I ran into a problem. When going through the form, the form goes through and redirects but the image doesn't actually get updated. When you go through the django admin, the image uploads fine.
If someone could take a look and see if something is missing, I've been staring at it for too long, so I need a fresh pair of eyes.
Business Models.py
class Business(models.Model):
name = models.CharField(verbose_name="Name", max_length=140)
desc = models.TextField(verbose_name="Description", null=True, blank=True)
bus_type = models.CharField(verbose_name="Business Type", choices=BUSINESS_TYPES, max_length=20)
location = models.CharField(_("location"), null=True, blank=True, max_length=200)
website = models.URLField(_("website"), null=True, blank=True, verify_exists=False)
created_by = models.ForeignKey(User, related_name="Created By")
admin = models.ManyToManyField(User, related_name="Admin User", null=True, blank=True)
followers = models.ManyToManyField(User, related_name="Followed by", null=True, blank=True)
date_added = models.DateField(verbose_name="Date Added")
class Meta:
verbose_name = "Business"
verbose_name_plural = "Businesses"
def __unicode__(self):
return self.name
class BusinessLogo(ImageModel):
business = models.ForeignKey(Business, related_name="Business Association")
My views.py
#login_required
def changeLogo(request, bus_id):
user = request.user
b = get_object_or_404(Business, pk = bus_id)
if request.method == 'POST':
form = ChangeLogoForm(request.POST, request.FILES, instance = b)
if form.is_valid():
biz_logo = form.save(commit=False)
biz_logo.save()
return HttpResponseRedirect('/')
else:
form = ChangeLogoForm()
return render_to_response('business/changelogo.html',
{'user': user, 'form':form, 'b':b}, context_instance=RequestContext(request))
Forms.py
class ChangeLogoForm(ModelForm):
class Meta:
model = BusinessLogo
def save(self, force_insert=False, force_update=False, commit=True):
f = super(ChangeLogoForm, self).save(commit=False)
if commit:
f.save()
print "form save method was called with commit TRUE"
return f
And finally my changelogo.html
...
{% block body %}
<h1>Change Logo</h1>
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Upload">
</form>
{% endblock %}
...
Thanks everyone, for taking a look.
Steve
The ChangeLogoForm's model is BusinessLogo, but when calling it's constructor you pass it a Business instance:
b = get_object_or_404(Business, pk = bus_id)
...
form = ChangeLogoForm(request.POST, request.FILES, instance = b)
(And you should probably use a OneToOneField field instead of ForeignKey)
Related
In my django app I have a User model that has a Boolean field of is_manager.
User model in models.py:
class User(AbstractUser):
name = models.CharField(max_length=15, null=True, blank=True)
last_name = models.CharField(max_length=15, null=True, blank=True)
title = models.CharField(max_length=50, null=True, blank=True)
email = models.EmailField(unique=True)
bio = models.TextField(null=True, blank=True)
company = models.ForeignKey(Company, on_delete=models.DO_NOTHING, null=True)
is_manager = models.BooleanField(default=False)
can_assign = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
I've been trying to create an edit page in order for managers and users to be able to change some of their fields.
Regular users should be able to change their bio and title, and the managers can change the can_assign Boolean.
I have a form that deals with the logic of that in forms.py:
class EditUserForm(ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
if self.user.is_manager:
super().__init__(**kwargs)
else:
super().__init__(**kwargs)
del self.fields['can_assign']
class Meta:
model = User
fields = ['title', 'can_assign', 'bio']
views.py:
#login_required
def editUser(request, pk):
user = User.objects.get(id=pk)
if request.user.is_manager or request.user == user:
#POST
if request.method == 'POST':
form = EditUserForm(request.POST, instance=user, user=request.user)
if form.is_valid():
form.save()
redirect('user-page', pk)
else:
print('nope')
#GET
form = EditUserForm(user=request.user, instance=user)
context = {'user': user, 'form': form}
return render(request, 'users/user_edit.html', context)
else:
return HttpResponse('<h1>Access Denied</h1>')
template:
{% extends 'main.html' %}
{% block content %}
<form method="POST" action="">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="Submit">
</form>
{% endblock content %}
for some reason the form.is_valid() method returns False. I have no idea why.
I have tried to use the .errors method on the form and on the form fields. No errors shown.
Thanks for any help!
" Oh! I completely missed that. I think the *args is required because that's how you pass in the request.POST. if you would have an explicit key like myform(data=request.POST) it would have worked because it would be in the *kwargs .. So it was basically failing cause it was acting like you were just initiating a new form, not submitting one –
Nealium
"
I have created this application but the problem I face now is one that has kept me up all night. I want users to be able to see and select only their own categories when they want to create a post. This is part of my codes and additional codes would be provided on request
category model
class Category(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1,related_name='categories_created')
name = models.CharField(max_length = 120)
slug = models.SlugField(unique= True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
post model
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1,related_name='posts_created') #blank=True, null=True)
title = models.CharField(max_length = 120)
slug = models.SlugField(unique= True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category_created', null= True)
addition codes would be provided immediately on request. Thanks
View.py in post app
def create(request):
if not request.user.is_authenticated():
messages.error(request, "Kindly confirm Your mail")
#or raise Http404
form = PostForm(request.POST or None, request.FILES or None)
user = request.user
categories = Category.objects.filter(category_created__user=user).distinct()
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
create_action(request.user, 'Posts', instance)
messages.success(request, "Post created")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
}
template = 'create.html'
return render(request,template,context)
Form
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [
"title",
"content",
"category",
]
html
{% if form %}
<form method="POST" action="" enctype="multipart/form-data">{% csrf_token %}
{{ form|crispy|safe }}
<input type="submit" name="submit" value="Publish">
</form>
{% endif %}
What you need to do is well-described here. Basically, you are using ModelForm which generates the form from your model. Your model doesn't know anything about filtering by user, so you will need to explicitly add a QuerySet to your form that only shows the desired categories. Change your "categories = ..." line to something like:
form.category.queryset = Category.objects.filter(user=user)
form.fields['category'].queryset = Category.objects.filter(user=user)</strike>
I am new to Django and need a help.
I want to allow users to update their account data using form, but struggle with associating Django User model with my UserProfile model, which extends default model with some additional fields.
I found, that solution is to create my own model form, but unfortunately I'm not exactly sure how to implement it.
models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User)
description = models.CharField(max_length=100, default='')
city = models.CharField(max_length=100, default='')
website = models.URLField(default='')
phone = models.IntegerField(default=0)
image = models.ImageField(upload_to='profile_image', blank=True)
def __str__(self):
return self.user.username
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender=User)
forms.py:
class EditProfileForm(UserChangeForm):
image = forms.ImageField(required=False)
city = forms.CharField(required=False)
class Meta:
model = User
fields = (
'email',
'first_name',
'last_name',
'password',
'image',
'city'
)
views.py:
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect(reverse('accounts:view_profile'))
else:
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/edit_profile.html', args)
edit_profile.html:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
You are looking for Inline formsets. Just read the docs, it's pretty simple.
I am very new to Django as well as Python. I am trying to build a small Resource management tool. Below is what I have come up with till now.
I Extended a User Model
I have created other required models like Current address Permanent Address etc.
I have a sample form in forms.py
I have a profile.html page.
As of now when a user is logged , and when he clicks on update profile he is redirected to Profile.html page where he gets fields from ModelForm Employee (Data pulled from DB) which is just a extended userModel. (Infact user should not be able to edit any of the field in this form, this should be just a read only field as this will be set by Admin, but this Problem is later part for me, I do not know how to bring as a ReadOnly field have not researched yet on this)
What I want to do is now I want to show all the other forms also (ModelForms of Current Address, Permanent address etc on the same same page for that particular user so he can update the records) Till now I tried different methods but I couldn't get hold of any proper solution Can anyone help me on this. Below are my models, views, forms and html page. I am open for any alternative solution which is easy and secure as this I have started recently so I am ok to change whatever required to be changed. All the other models are linked to foreign Key emp_id from Employee model. Apologies for the Long question but I am stuck at this point and I unable to go ahead from this point.
Forms:
#User Profile Form to update the user profile
class UserProfileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserProfileForm, self).__init__(*args, **kwargs)
# If you pass FormHelper constructor a form instance
# It builds a default layout with all its fields
self.helper = FormHelper(self)
# You can dynamically adjust your layout
helper = FormHelper()
helper.form_class = 'form-horizontal'
helper.layout = Layout(
Field('text_input', css_class='input-xlarge'),
Field('textarea', rows="3", css_class='input-xlarge'),
'radio_buttons',
Field('checkboxes', style="background: #FAFAFA; padding: 10px;"),
AppendedText('appended_text', '.00'),
PrependedText('prepended_text', '<input type="checkbox" checked="checked" value="" id="" name="">', active=True),
PrependedText('prepended_text_two', '#'),
'multicolon_select',
FormActions(
Submit('save_changes', 'Save changes', css_class="btn-primary"),
Submit('cancel', 'Cancel'),
)
)
self.helper.layout.append(Submit('save_changes', 'Update'))
class Meta:
model = Employee
exclude = ('user',)
Views:
#login_required
def user_profile(request):
if request.method == 'POST':
form = UserProfileForm(request.POST, instance=request.user.profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/loggedin/')
else:
user = request.user
profile = user.profile
form = UserProfileForm(instance=profile)
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('profile.html', args)
profile.html:
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h2> Profile </h2>
{% crispy form %}
{% endblock %}
Models.
#Department Model
class Dept(models.Model):
dept_name = models.CharField(max_length=30)
def __unicode__(self):
return self.dept_name
#Extending User Model
class Employee(models.Model):
user = models.OneToOneField(User, null=True, blank = True, verbose_name="User Id")
emp_id = models.IntegerField(primary_key=True, max_length=5, verbose_name="Employee Id")
emp_first = models.CharField('First Name',max_length=20)
emp_middle = models.CharField('Middle Name', blank=True, max_length=20)
emp_last = models.CharField('Last Name',max_length=20)
emp_email = models.EmailField('Email Id')
emp_dept = models.ForeignKey(Dept, verbose_name="Department")
def __unicode__(self):
return self.emp_first
User.profile = property(lambda u: Employee.objects.get_or_create(user=u)[0])
#Current Address Model
class CurrentContact(models.Model):
emp = models.ForeignKey(Employee)
emp_add = models.TextField('Current Address')
emp_city = models.CharField('City', max_length=20, default = 'Bangalore')
emp_state = models.CharField('State', max_length=20, default= 'Karnataka')
emp_country = models.CharField('Country', max_length=20, default = 'India')
emp_mobile1 = models.IntegerField('Mobile1',max_length=12)
emp_mobile2 = models.IntegerField('Mobile2', null=True, blank=True, max_length=12)
emp_landline = models.IntegerField('Land Line',null=True, blank=True, max_length=12)
emp_PerEmail = models.EmailField('Personal Email Id', blank=True)
def __unicode__(self):
return self.emp
#Permanent Address Model
class PermanentContact(models.Model):
emp = models.ForeignKey(Employee)
emp_add = models.TextField('Permanent Address')
emp_city = models.CharField('City', max_length=20, default = 'Bangalore')
emp_state = models.CharField('State', max_length=20,default= 'Karnataka')
emp_country = models.CharField('Country', max_length=20, default = 'India')
emp_mobile1 = models.IntegerField('Mobile1',max_length=12)
emp_mobile2 = models.IntegerField('Mobile2', null=True, blank=True, max_length=12)
emp_landline = models.IntegerField('Land Line',null=True, blank=True, max_length=12)
emp_PerEmail = models.EmailField('Personal Email Id', blank=True)
def __unicode__(self):
return self.emp
#Emergency Contact Model
class Emergency(models.Model):
emp = models.ForeignKey(Employee)
emrg_name = models.CharField('Full Name', max_length=30)
emrg_add = models.TextField('Full Address')
emrg_city = models.CharField('City', max_length=20, default = 'Bangalore')
emrg_state = models.CharField('State', max_length=20,default= 'Karnataka')
emrg_country = models.CharField('Country', max_length=20, default = 'India')
emrg_mobile1 = models.IntegerField('Mobile1', max_length=12)
emrg_mobile2 = models.IntegerField('Mobile2', null=True, blank=True, max_length=12)
emrg_landline = models.IntegerField('Land Line',null=True, blank=True, max_length=12)
emrg_PerEmail = models.EmailField('Email Id', blank=True)
def __unicode__(self):
return self.emp
Have you taken a look here:
Django: Changing User Profile by forms
It seems like an almost identical question to yours.
I want to save an add under the current user that i'm logged in as, but i keep getting the error outlined in the subject.
My models:
class CustomUser(User):
nickname = models.CharField(max_length=255)
phone = models.CharField(max_length=255)
address = models.CharField(max_length=255)
objects = UserManager()
city = models.ForeignKey(locations, unique=False)
def __str__(self):
return self.nickname
class Admin:
pass
class listings(models.Model):
title = models.CharField(max_length=255)
category = models.ForeignKey('category')
description = models.CharField(max_length=255)
published = models.DateField(auto_now=True)
user = models.ForeignKey(CustomUser, unique=False)
def __str__(self):
return self.naslov
class Admin:
pass
The form:
class jobOfferForm(forms.ModelForm):
title = forms.CharField(max_length=255)
description = forms.CharField(max_length=255)
category = forms.ModelChoiceField(queryset=kategorii.objects.all())
class Meta:
model = listings
The template:
<div class="span8">
<form action="" method="POST">
{% csrf_token %}
{{form.as_p}}
<input type="submit" name="submit" value="Save"/>
</form>
</div>
The view!
def displisting(request):
if request.method == 'POST':
form = jobOfferForm(request.POST)
if form.is_valid():
title = form.cleaned_data['title']
description = form.cleaned_data['description']
new_listng = form.save(commit = False)
new_listng.user = request.user
new_listng.object.save()
return HttpResponseRedirect('/listing/review')
else:
form = jobOfferForm()
return render(request,'listings.html',{'form':form,})
I fear the custom user is preventing me from doing that?
But i need the extra attributes?
this error will happen if your user is not logged in.
login using the bundled /admin site and your request.user object will be a valid User instance
request.User isn't an instance of your custom CustomerUser, it's a django.contrib.auth.models.User. Hence the assignment:
new_listng.user = request.user
isn't valid.
You probably want your request.User to be downcast to your CustomerUser (or other subclasses, if you have them). You can add a custom middleware, modeled off django.contrib.auth.middleware.AuthenticationMiddleware that does this.
django-model-util's InheritanceManager has some useful helpers like select_subclasses that make this easy.