0

Basically, I'm trying to get the current user type, by using the OneToOne models you can see below and display different template "parts" specific for each model. I researched a bit and found out about type() and hasattr(). I was wondering if there's any way I can use them in templates or do you have any better suggestions? Thanks!

models.py

class Type1(models.Model):
user            = models.OneToOneField(User)
company_name    = models.CharField(max_length=100)

    def __unicode__(self):
        return self.company_name

class Type2(models.Model):
user            = models.OneToOneField(User)
first_name      = models.CharField(max_length=30)
second_name     = models.CharField(max_length=30)

    def __unicode__(self):
        return self.first_name

views.py

def Type1Registration(request):
if request.user.is_authenticated():
    return HttpResponseRedirect('/')
if request.method == 'POST':
    form = Type1Form(request.POST)
    if form.is_valid():
        user = User.objects.create_user(username=form.cleaned_data['username'], 
            email=form.cleaned_data['email'], password=form.cleaned_data['password'])
        user.save()
        type1 = Type1(user=user, company_name=form.cleaned_data['company_name'])
        type1.save()
        return HttpResponseRedirect('/')
    else:
        return render(request, 'type1_register.html', {'form': form})
else:
    form = Type1Form()
    context = {'form': form}
    return render(request, 'type1_register.html', context)

def Type2Registration(request):
if request.user.is_authenticated():
    return HttpResponseRedirect('/')
if request.method == 'POST':
    form = Type2Form(request.POST)
    if form.is_valid():
        user = User.objects.create_user(username=form.cleaned_data['username'], 
            email=form.cleaned_data['email'], password=form.cleaned_data['password'])
        user.save()
        type2 = Type2(user=user, first_name=form.cleaned_data['first_name'],
            second_name=form.cleaned_data['second_name'])
        type2.save()
        return HttpResponseRedirect('/')
    else:
        return render(request, 'type2_register.html', {'form': form})
else:
    form = Type2Form()
    context = {'form': form}
    return render(request, 'type2_register.html', context)
Supperino
  • 3
  • 1
  • 4

1 Answers1

0

This is though as you have two different models. The thing I would consider here is to make one model and do it like this:

class UserComplete(AbstractUser):
    first_name      = models.CharField(max_length=30)
    second_name     = models.CharField(max_length=30)
    company_name    = models.CharField(max_length=100)
    company         = models.BooleanField(default=False)

    def get_name(self):
        "Returns the person's or business name."
        if self.company:
            return self.company_name
        else:
            return self.first_name

One thing I should mention here is that I am not completely sure what you want to do with the models, so I am not sure if this is indeed the best solution for you. I also used AbstractUser which is something you might not be familiar with. Basically, it extends the User class, which is, in my opinion the best way to extend the User model. More information about that here: https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#specifying-custom-user-model

Then you have two choices. For your forms, you could create two separate forms or one. This again, depends on what you want to do with the models and where you want to edit your stuff if something has to be changed.

Here are the two forms, if you want to go that way:

class UserCreateForm(UserCreationForm):    
    class Meta:
        model = UserComplete
        fields = ("email", "username", "password", "first_name", "second_name")

class BusinessCreateForm(UserCreationForm):  
    class Meta:
        model = UserComplete
        fields = ("email", "username", "password", "company_name")

Or with just one:

class CreateForm(UserCreationForm):    
    company_name = forms.CharField(required=False)  
    first_name = forms.CharField(required=False)  
    second_name = forms.CharField(required=False)

    class Meta:
        model = UserComplete
        fields = ("email", "username", "password", "company_name", "first_name", "second_name", "company")

You will have to render the form manually in your template and don't display the ones you don't want. Read here if you need more info about that: https://docs.djangoproject.com/en/1.10/topics/forms/#rendering-fields-manually. With the first form option, you will have to process each form separately, like you did in your views.py. With the second option you can render one form and use the boolean from company to determine which fields need to be processed.

Yet again, I want to say that this fully depends on what you are building. With the second option you can do something like {% if request.user.company %} in your templates. Your original code doesn't have that option. Although, there is a workaround for that. You can do: {% if request.user.type1.company_name %} it will check if the value exists. In my opinion this is a bit dirty, but it will work, though. Note: if the value is empty (a business without name) it will return false.

Let me know if you need an example of the views.py for the second form. Hope this helps. Have fun! :)

P.S. I would replace this:

if request.user.is_authenticated():
    return HttpResponseRedirect('/')

With login_required. Read more about that here: https://docs.djangoproject.com/en/1.10/topics/auth/default/#django.contrib.auth.decorators.login_required

1GDST
  • 821
  • 1
  • 8
  • 13
  • Is extending the AbstractUser the only way to achieve this? I mean, I wouldn't really like to remake the entire system. I already created the entire authentification (models, views, forms, auth templates), the only thing I'm stuck at are the templates for post-login, to display different parts for each user type. Ohh, and about the single model. For my project, I would need like 10-20 fields for each model and I don't think this would be the best idea. – Supperino Oct 02 '16 at 16:56
  • You can do: `{% if request.user.company_name %}` in your template, which basically answers your question. It will check if the field is true (it contains something) or false (it doesn't exist or is Null). Unfortunately it is not easy this way to get less code in the `views.py`. There are ways to achieve it, but those are not best practices. One other thing you could do is CBV, which will reduce the code, but that's something that should be done over the whole project. Read: https://docs.djangoproject.com/en/1.10/topics/class-based-views/intro/ – 1GDST Oct 02 '16 at 17:07
  • Tried this in my profile template, not working. `

    Hey there,

    {% if request.user.company_name %}

    Company

    {% elif request.user.first_name %}

    Freelancer

    `
    – Supperino Oct 02 '16 at 17:31
  • I am sorry, my bad, it should be {% if request.user.type1 %} or {% if request.user.type1.company_name %} – 1GDST Oct 02 '16 at 17:39
  • Goosh, I don't know how to thank you enough! I was stuck on this for like 3 days, thank you very much! – Supperino Oct 02 '16 at 17:42