User has no dcf_profile : RelatedObjectDoesNotExist

85 views
Skip to first unread message

Nabil BOUDERBALA

unread,
Jun 16, 2017, 7:06:33 AM6/16/17
to Django users

After extending an existing user model, I get RelatedObjectDoesNotExist exception with a value User has no dcf_profile. I seems that dcf_profile isn't created automatically for each user.

Please take a look at my model, view and form below and tell me how can I correct my views file?

My models.py :

class CustomUser(models.Model):
    auth_user_ptr = models.OneToOneField(
                                User,
                                parent_link=True,
                                related_name='dcf_profile',
                                primary_key=True
                            )
    phone = models.CharField(_('phone'), max_length=30, null=True, blank=True)
    receive_news = models.BooleanField(_('receive news'), default=True, db_index=True)
    class Meta:
        app_label = 'dcf'
    def allow_add_item(self):
        if self.item_set.count() > settings.DCF_ITEM_PER_USER_LIMIT:
            return False
        else:
            return True

class Item(models.Model):
    slug = models.SlugField(blank=True, null=True, max_length=100)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, verbose_name=_('group'))
    title = models.CharField(_('title'), max_length=100)
    description = models.TextField(_('description'))
    price = models.DecimalField(_('price'), max_digits=10, decimal_places=2)
    phone = models.CharField(_('phone'), max_length=30)
    is_active = models.BooleanField(_('display'), default=True, db_index=True)
    updated = models.DateTimeField(_('updated'), auto_now=True, db_index=True)
    posted = models.DateTimeField(_('posted'), auto_now_add=True)
    def __unicode__(self):
        return self.title
    class Meta:
        verbose_name = _('item')
        verbose_name_plural = _('items')
        ordering = ('-updated', )
    def get_absolute_url(self):
        return reverse('item', kwargs={
            'pk': self.pk,
            'slug': self.slug
        })
    def get_title(self):
        return u'%s' % self.title
    def get_description(self):
        return u'%s' % self.description[:155]
    def get_keywords(self):
       # TODO need more optimal keywords selection
        return ",".join(set(self.description.split()))
    def get_related(self):
       # TODO Need more complicated related select
        return Item.objects.exclude(pk=self.pk)[:settings.DCF_RELATED_LIMIT]
    def save(self, *args, **kwargs):
        if self.slug is None:
            self.slug = slugify(unidecode(self.title))
        super(Item, self).save(*args, **kwargs)

My views.py :

class ItemCreateView(FormsetMixin, CreateView):
is_update_view = False
model = Item
form_class = ItemCreateEditForm
formset_class = inlineformset_factory(Item, Image, extra=3, fields=('file', ))

@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
    if not self.request.user.dcf_profile.allow_add_item():
        messages.error(self.request, _('You have reached the limit!'))
        return redirect(reverse('my'))
    return super(ItemCreateView, self).dispatch(*args, **kwargs)
def form_valid(self, form, formset):
    form.instance.user = self.request.user
    form.save()
    return super(ItemCreateView, self).form_valid(form, formset)

My forms.py

class ItemCreateEditForm(forms.ModelForm):
class Meta:
    model = Item
    fields = ('group', 'title', 'description', 'price', 'phone', 'is_active')

Abraham Varricatt

unread,
Jun 16, 2017, 7:36:32 AM6/16/17
to Django users

On Friday, June 16, 2017 at 7:06:33 AM UTC-4, Nabil BOUDERBALA wrote:

After extending an existing user model, I get RelatedObjectDoesNotExist exception with a value User has no dcf_profile. I seems that dcf_profile isn't created automatically for each user.


It took me awhile to figure out that dcf_profile is the text you use as related_name for the User model. 


 

Please take a look at my model, view and form below and tell me how can I correct my views file?

My views.py :
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
    if not self.request.user.dcf_profile.allow_add_item():

It looks like this is where you are having trouble. The code is trying to call the dcf_profile attribute/method from the user object - which doesn't exist. 

Your end goal appears to be to call the all_add_item() function. Why not grab an instance of your CustomUser first and invoke it on that? Something like,

def dispatch(self, *args, **kwargs):
    user
= self.request.user
    my_user
= CustomUser.objects.get(auth_user_ptr=user)  # Assuming you have entry in your database
   
if not my_user.allow_add_item():


Yours,
Abraham V.

Nabil BOUDERBALA

unread,
Jun 16, 2017, 10:40:30 AM6/16/17
to Django users
I did as you said and I get DoesNotExist, CustomUser matching query does not exist.
I have changed the code to :
user = self.request.user my_user = CustomUser.objects.get_or_create(auth_user_ptr=user) # Assuming you have entry in your database if not my_user.allow_add_item():
but I get AttributeError 'tuple' object has no attribute 'allow_add_item'.
Maybe the Item model should have a foreign key to the CustomUser model instead of the User model, because allow_add_item() is in the Item model. However, when I change the foreignkey, I get a cannot query "user" error.
For additional details, please take a look at users.py and the app with the extended user model views.py
I am not sure whether I can put the def allow_add_item(self): of the CustomUser directly in the django User model.

Melvyn Sopacua

unread,
Jun 16, 2017, 11:07:42 AM6/16/17
to django...@googlegroups.com

On Friday 16 June 2017 03:17:00 Nabil BOUDERBALA wrote:

> After extending an existing user model, I get

> RelatedObjectDoesNotExist exception with a value User has no

> dcf_profile. I seems that dcf_profile isn't created automatically for

> each user.

 

That's correct. That's your job and the documentation gives you a hint on how to do it:

 

These profile models are not special in any way - they are just Django models that happen to have a one-to-one link with a user model. As such, they aren’t auto created when a user is created, but a django.db.models.signals.post_save could be used to create or update related models as appropriate.

 

--

Melvyn Sopacua

Nabil BOUDERBALA

unread,
Jun 17, 2017, 6:15:39 AM6/17/17
to Django users
Just to share with you the solution that worked, I have created a proxy model of the User model and used the code that abraham provided me :

Updated models.py

class DcfUser(User):
    class Meta:
        proxy = True
    def allow_add_item(self):
        if self.item_set.count() > settings.DCF_ITEM_PER_USER_LIMIT:
            return False
        else:
            return True

Updated views.py

@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
    user = self.request.user
    my_user = DcfUser.objects.get(username=user)
    if not my_user.allow_add_item():
        messages.error(self.request, _('You have reached the limit!'))
        return redirect(reverse('my'))

Thank you


On Friday, June 16, 2017 at 1:06:33 PM UTC+2, Nabil BOUDERBALA wrote:
Reply all
Reply to author
Forward
0 new messages