0

I have a django app with which every registered user can create categories. For the authentication I am using django-all-auth. My models.py looks like this:

class Profile(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    create_date = models.DateTimeField('date added', auto_now_add=True)
    modify_date = models.DateTimeField('date modified', default=timezone.now)

class Category(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(Profile, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, unique=True)
    create_date = models.DateTimeField('date added', auto_now_add=True)
    modify_date = models.DateTimeField('date modified', default=timezone.now)

On the index page the user can see the created categories and create new ones. The views.py:

def CategoryView(request):
    user = 0
    if request.user.is_authenticated():
        user = request.user
    form = CategoryNameForm()
    form.user = user
    context = {
        'categories': Category.objects.all(),
        'form': form,
        'user':user,
        }
    if request.method == 'POST':
        form = CategoryNameForm(request.POST)
        form.user = user
        if form.is_valid():
            form.save()
    return render(request, 'myapp/index.html',context) 

forms.py: class CategoryNameForm(forms.ModelForm):

    class Meta:
        model = Category
        fields = ('name',)

The authentication works. So I was thinking to just put pass the user field into the form :

class CategoryNameForm(forms.ModelForm):

        class Meta:
            model = Category
            fields = ('name','user',)

hide it and then, just select it via JS since the user is in the context. I was just wondering if there is an easier way. This form.user = user for some reason didn't work, I get a NOT NULL constraint failure

1
  • so you want to make sure just logged in users can access? how about @login_required in the view.py file? Commented May 26, 2017 at 20:50

1 Answer 1

1

There are couple of ways but here is one:

class CategoryNameForm(forms.ModelForm):
    class Meta:
        model = Category
        fields = ('name',)  # take out user you don't need it here

    def save(self, **kwargs):
        user = kwargs.pop('user')
        instance = super(CategoryNameForm, self).save(**kwargs)
        instance.user = user
        instance.save()
        return instance

Then in view:

if form.is_valid():
    form.save(user=request.user, commit=False)

Make sure your CategoryView is only accessible by authenticated user. Otherwise you will still get NOT NULL constraint failure for user.

Sign up to request clarification or add additional context in comments.

4 Comments

this worked, perfect thanks, I had to change this line though to instance.user = Profile.objects.get(user=user)
Yes correct, got confused by your naming convention :) P.S you can also do just instance.user = user.profile
it's pretty terrible, any advice where I could learn better naming conevntions?
You just need to think more :) You have ForeignKey to Profile but column name is user, doesn't make sense right? (unless you have a strong reason or need) profile = models.ForeignKey(Profile) makes more sense. For Python coding guidlines you can check pep-8 and to validate your files against some guidelines you can use pycodestyle

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.