Home > Software design >  Django how to reverse to autocreated page
Django how to reverse to autocreated page

Time:08-01

I have a CustomUser model and a UserProfile model. The UserProfile is linked to the CustomUser via a foreign key. A new UserProfile is auto created whenever a new CustomUser is created.

After a new CustomUser is added, I want to land on the UserProfile page so the person adding the user can also edit the profile. I have not been able to figure out how to specify the UserProfile id in the view for adding the new user.

The models:

class UserProfile(models.Model):
    user = models.OneToOneField(CustomUser, null=True, on_delete=models.CASCADE)
    preferred_name = models.CharField(null=True, blank=True, max_length= 75)
    pronouns = models.CharField(null=True, blank=True, max_length= 40)
    phone = PhoneField(blank=True, help_text='Contact phone number')
    job_title = models.CharField(null=True, blank=True, max_length= 75)
    birthdate = models.DateField(null=True, blank=True)
    bio = tinymce_models.HTMLField(null=True, blank=True)
    profile_image = ConstrainedFileField(
        null=True,
        blank=True,
        upload_to='projects/employee_profiles',
        content_types=['image/png', 'image/jpg', 'image/jpeg', 'image/gif'],
        max_upload_size=2097152,
    )

    def create_user_profile(sender, instance, created, **kwargs):
      if created:
            UserProfile.objects.create(user=instance)

   post_save.connect(create_user_profile, sender=CustomUser)


class CustomUser(AbstractUser):
    full_name = models.CharField(max_length=250, null=True)
    age = models.PositiveIntegerField(null=True, blank=True)
    employee_type = models.ForeignKey(Group, null=True, on_delete=models.SET_NULL, default=1)
    is_active = models.BooleanField(null=False, default=True)

The view:

class AddCompanyEmployee(CreateView):
    model = CustomUser
    template_name = 'manage/add_employee.html'
    form_class = AddCompanyEmployeeForm

    def get_success_url(self):
        return reverse('userprofile_detail', args=[self.kwargs.get('userprofile_pk')])

The form:

class AddCompanyEmployeeForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = UserCreationForm.Meta.fields   ('email', 'full_name', 'age',)

The UserProfile URL:

from django.urls import path
from .views import EmployeeDirectory, UserProfileDetailView

urlpatterns = [
    path('', EmployeeDirectory.as_view(), name='directory'),
    path('profile/<int:pk>', UserProfileDetailView.as_view(), name='userprofile_detail'),
]

This is the error I get when I add a new user:

NoReverseMatch at /manage/add_employee/
Reverse for 'userprofile_detail' with arguments '(None,)' not found. 2 pattern(s) tried: ['user\\-profiles/profile/(?P<pk>[0-9] )\\Z', 'directory/profile/(?P<pk>[0-9] )\\Z']

CodePudding user response:

You can work with:

class AddCompanyEmployee(CreateView):
    model = CustomUser
    template_name = 'manage/add_employee.html'
    form_class = AddCompanyEmployeeForm

    def get_success_url(self):
        return reverse(
            'userprofile_detail', kwargs={'pk': self.object.userprofile.pk}
        )

It will look for the OneToOneField in reverse, and thus obtain the .pk of the related UserProfile.

That being said it is quite strange that you use both a CustomUser and UserProfile. Usually if you implement your own user model, that is to add fields that you would otherwise store in a UserProfile, and thus to prevent having to work with two models.

  • Related