How to upload photo into UserProfile for specified user in django? - python

I have a photo field in my UserProfile model, so any user is able to upload his photo. I was thinking that all I need is ModelForm for the UserProfile, but without User specified it will fail, of course. But if I pass the request.user as a parameter into a form constructor - it won't work, too, because of the thing that form's UserProfile isn't connected with this user.
class ProfileUploadPhotoForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('photo',)
Is there any way to set, which user's profile to modify?

You need to pass it an instance of a UserProfile to update.
uploadform = ProfileUploadPhotoForm(request.POST, request.FILES,\
instance=request.user.userprofile)
if uploadform.is_valid():
uploadform.save()

Problem solved!
I forgot to add
enctype="multipart/form-data"
in form attributes.

Related

How can I use an extended user model in a DetailView?

I've got a Django view in charge of showing a user profile. I'm using the user model provided by django itself but I also would like to extend it with some of my own information, So I made my own model to extend the user model itself:
class UserProfile(AbstractBaseUser):
is_verified = models.BooleanField(default=True)
current_profile = models.ImageField(default=static('img/default_profile.jpg'))
ratings = models.ManyToManyField(Video, through='UserProfileVideoRating', related_name='ratings')
views = models.ManyToManyField(Video, through='UserProfileVideoView', related_name='views')
CommentRating = models.ManyToManyField(Comment, through='UserProfileCommentRating', related_name='CommentRating')
subscriptions = models.ManyToManyField(User)
And here is my view I'd like to use for that:
User = get_user_model()
# Create your views here.
class profileDetailView(DetailView):
template_name = 'profile.html'
def get_object(self):
username = self.kwargs.get("username")
if username is None:
raise Http404
return get_object_or_404(User, username__iexact=username, is_active=True)
Now my question is, seeing as DetailViews are meant for a single model, How can I achieve this?
You're confused between two ways of extending the built-in User model.
If you're inheriting from AbstractBaseUser, that means you're defining your own user model - you would need to define its own username/email fields etc, and set the AUTH_USER_MODEL to point to your replacement model. In this case, you wouldn't need to reference two models in your template because your model would be the User.
However if you want to define a related UserProfile, you don't need to inherit from AbstractBaseUser, and you don't need to change AUTH_USER_MODEL; but you do need to define a relation with the actual User model, probably via a one-to-one field. In this case, to get access to the profile you just follow the relationship in the template - eg via {{ user.userprofile.currentprofile }} etc.
In your case I would advise taking the second option; remove the inheritance from AbstractBaseUser and add a one-to-one field to User.

Indirect inline in Django admin

I have the following models:
class UserProfile(models.Model):
user = models.OneToOneField(User)
class Property(models.Model):
user = models.ForeignKey(User)
I would like to create a TabularInline displaying every Property connected to a particular UserProfile on its Django admin page. The problem here is, of course, that Property does not have a ForeignKey directly to UserProfile, so I cannot simply write
class PropertyTabularInline(admin.TabularInline):
model = Property
class UserProfileAdmin(admin.ModelAdmin):
inlines = (PropertyTabularInline,)
How can I easily do what I want?
You can overwrite the User admin page to display both the Profile and the Property models.
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from myapp.models import *
class ProfileInline(admin.TabularInline):
model = Profile
class PropertyInline(admin.TabularInline):
model = Property
class UserAdmin(UserAdmin):
inlines = (ProfileInline, PropertyInline,)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
You can also remove any unwanted/unused User properties from being displayed (e.g. Groups or Permissions)
more here: https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#extending-the-existing-user-model
and here:
https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#a-full-example
class PropertyTabularInline(admin.TabularInline):
model = Property
def formfield_for_dbfield(self, field, **kwargs):
if field.name == 'user':
# implement your method to get userprofile object from request here.
user_profile = self.get_object(kwargs['request'], UserProfile)
kwargs["queryset"] = Property.objects.filter(user=user_profile)
return super(PropertyInLine, self).formfield_for_dbfield(field, **kwargs)
once this is done, you can add this inline to user UserProfileAdmin like:
class UserProfileAdmin(admin.ModelAdmin):
inlines = (PropertyTabularInline,)
Haven't tested it, but that should work.
It is achievable by making one change in your models.
Instead of creating OneToOne relationship from UserProfile to User, subclass User creating UserProfile. Code should look like that:
class UserProfile(User):
# some other fields, no relation to User model
class Property(models.Model):
user = models.ForeignKey(User)
That will result in creating UserProfile model that have hidden OneToOne relation to User model, it won't duplicate user model.
After doing that change, your code will work. There are some changes under the hood, like UserProfile no longer have it's own ID, you can access fields from User inside UserProfile and it's hard to swap User model using settings.AUTH_USER_MODEL (that will require creating some custom function returning proper type and changing migration by hand) but if this is not a problem for you, it may be good solution.

use MyUser to auth in django

Asking for your help, because can't find right answer by myself. I made custom registration form in django with additional fields. To save that fields in database i made custom user in my models. And it works ok(as i understand). But it seems that auth is using the old User model. I have two thoughts:
1- I need to overwrite some method in MyUser.
2- I found some information about adding AUTH_USER_MODEL variable in my settings ( but it call some errors)
forms.py
class MyRegistrationForm(UserCreationForm):
bdate=forms.DateField(required=True)
phone=forms.CharField(required=True)
captha=CaptchaField(required=True)
class Meta:
model=MyUser
fields=('username','first_name','last_name','email','bdate','phone','password1','password2')
def save(self, commit=True):
user = super(MyRegistrationForm, self).save(commit=False)
user.bdate=self.cleaned_data['bdate']
user.phone=self.cleaned_data['phone']
if commit:
user.save()
return user
models.py
class MyUser(User):
bdate=models.DateField()
phone=models.CharField(max_length=10)
You should not inherit from User, which is a concrete class. Inherit from AbstractUser instead.

Django - Custom admin save model

I have two models: Page and a custom user model MyUser
These two models have each one a manytomanyfield:
class Page(models.Model):
members = models.ManyToManyField(settings.AUTH_USER_MODEL)
class MyUser(AbstractUser):
mypages = models.ManyToManyField(Page)
objects = UserManager()
When I add a member to the members manytomanyfield via the admin interface, I would like to add the new attributed Page object to the user automatically in the mypages attribute, so I am trying to override the save method of the Page model in the admin.py:
class PageAdmin(admin.ModelAdmin):
def save_related(self, request, form, formsets, change):
super(ModelAdmin, self).save_related(request, form, formsets, change)
if 'members' in form.changed_data:
#And I am quite lost....
Is it a good idea? Should I do that in the "Page model custom save" method in my models.py file either doing it in the admin.py?
I tried to replace the #And I am quite lost.... part with ideas from:
Link1
Link2
Without any sucess!
This is completely mistaken. A many-to-many field is already double-ended. You don't need to define it on both ends. When you define a members field on Page, then MyUser will automatically get a page_set accessor which is the other end of the relation, and any page that adds a user to its members will automatically show up in the user's page_set. There is no need for any code.

Django User Profile - Forms

Django 1.4
Sorry if this is a silly question i am fairly new to Django.
I am attempting to link a user and a profile together via the inbuilt auth profile system. All the examples of this i can find do not use a class based view, which is something i would really like to use.
Basically i would like a form that combines the Profile and the User allowing me to create both at the same time. If possible i would like to use the same form to Edit/Create the User + Profile.
I have created a model for the profile: Profile
Created forms:
class UserForm(forms.ModelForm):
class Meta:
model = User
class ProfileRegisterView(FormView):
template_name = 'profile-register-form.html'
form_class = UserForm
success_url = '/account/created/'
Adding the profile to the user model does not seem to include it within the UserForm:
AUTH_PROFILE_MODULE = "creative_profile.Profile"
The 2nd alternative i have tried was to define individual forms in forms.py however the form_class attribute only accepts one form model..
Any pointers help would be great, thanks
One possible solution is to include the Profile fields in your UserForm and override the save() method to populate the Profile fields.
The save() method will have to include a get_or_create() call for the Profile model if you're not using a post_save signal to create it. If you are using a post_save signal to create the Profile model, you're going to have to make sure the User is being saved first before calling the get_profile() method.
I do it in more simple way (i suggest). Just use django build in. In urls.py I added (r'^login/$','django.contrib.auth.views.login'). In settings.py add LOGIN_URL='/login/' and to MIDDLEWARE_CLASSES add 'django.contrib.auth.middleware.AuthenticationMiddleware'. Copy registration/login.html template locally if you want to change it. After such manipulations you will have ability to login as user. Forgot, you also should import from django.contrib.auth.models User and Group.

Categories

Resources