1

I was having trouble with registration on my Django app, but I finally got it to post successfully with two forms that ask for username, password, password confirmation, city, and email address. When I go to the Django admin page, I can see that the custom user has been created, but the email field is missing. I've run syncdb several times, so I think that's taken care of, so what is the problem?

Here is the extended form from forms.py:

class UserWaitlistForm(forms.Form):
    user_city = forms.CharField(max_length=25, required=True)
    user_email = forms.EmailField(max_length=35)
    fields = ('user_city,' 'user_email')

Here is the register view from views.py:

@atomic
def register(request):
    user_form = UserCreationForm()
    user_waitlist_form = UserWaitlistForm()

    if request.method == 'POST':
        user_form = UserCreationForm(request.POST)
        user_waitlist_form = UserWaitlistForm(request.POST)

    if user_form.is_valid() and user_waitlist_form.is_valid():
        new_user = user_form.save()
        Foodie.objects.create(user_wechat=new_user, user_email=user_waitlist_form['user_email'].value(), user_city=user_waitlist_form['user_city'].value())

        return redirect(reverse('home'))

    return render(request, "registration/register.html", {
        'user_form': user_form,
        'user_waitlist_form': user_waitlist_form,
    })

Here is the extended user model from models.py:

class Foodie(models.Model):
    user_wechat = models.OneToOneField(User)
    user_city = models.CharField(max_length=25)
    user_waitlist_status = models.BooleanField(default=False)
    user_waitlist_num = models.IntegerField(blank=True, default=0)
    user_num_referrals = models.IntegerField(blank=True, default=0)
    user_email = models.EmailField()

    USERNAME_FIELD = 'user_wechat'

def __unicode__(self):
    return self.user_wechat.username

Here is my register.html:

{% extends "base.html" %}
{% load staticfiles %}
{% block title %}Create an account{% endblock %}
{% block content %}
<div data-role="page" id="register" data-theme="a">

    <div data-role="header" data-position="fixed" style="background-color:#EEEEEE;" data-tap-toggle="false" data-add-back-btn="true">
        <h1>Register</h1>
    </div><!-- /header -->
  <h1>Create an account</h1>

  <form action="" method="post">
    {{ user_form.as_p }}
    {{ user_waitlist_form.as_p }}
    <input type="submit" value="Create an account"/>
    {% csrf_token %}
  </form>
{% endblock %}

I recalled two problems that may have been related:

  1. When I ran python manage.py migrate, I got 'django.db.utils.ProgrammingError: relation "chishenma_app_category" already exists,' so I ran it again with --fake and that seemed fine. The category model isn't part of the registration form though, so maybe this problem isn't actually related. Just in case, though, here is the Category model:

    class Category(models.Model):
        category_label = models.CharField(max_length=200)
        category_img = models.ImageField(upload_to='images/', null=True, blank=True)
        category_tag = models.CharField(max_length=200, blank=True)
        def __unicode__(self):
            return self.category_label
    
  2. This Stack Overflow thread suggests I delete the already-existing table from my database, but when I went into the psql shell (I'm using 9.2) and typed \d or \dt db_chishenma (the database name), it said, "No relations found"/"No matching relations found" even though \list returned a list that included my database (db_chishenma).

It seems that something is up with my database. Clearly a database exists, but how do I access it and delete the chishenma_app_category table? Will this solve the problem of the missing email address?

Community
  • 1
  • 1
Michelle Glauser
  • 1,097
  • 16
  • 28

2 Answers2

1

Regarding your use of psql, the command \dt db_chishenma will look for a table named db_chishenma, which is why you got the No relations found error.

You can either connect to the db from the cmdline directly by specifying it as the last argument, i.e.

psql -h <host> -U <user> -p <port> <dbname>

Or you can use \c db_chishenma to connect to that DB from within psql (if you were connected to another DB on the same server).

I usually use the from-the-cmdline approach.

Once connected to that DB, then you want to list your table: \dt chishenma_app_category, which should be found once connected to the DB, since the error was it already existed.

You can then run this SQL to drop the table:

DROP TABLE chishenma_app_category; COMMIT;

The COMMIT is only necessary if you don't have auto-commit enabled.

Edit with response to OP's comment:

Did the email field actually get added to the table in Postgres after you re-synched?

Also, you might want to try increasing the verbosity when doing the sync, to see if that yields any extra information. This is done with the option --verbosity 2. You can crank it up to 3 for even more info.

It sounds like South may be out of sync with the DB. Depending on what the increased verbosity says, it may be advisable to follow the other steps from the ticket you linked regarding the South migration files and history.

khampson
  • 14,700
  • 4
  • 41
  • 43
  • Oh, I see, thanks. When I dropped the table, I had to do a CASCADE drop. Then I deleted my migrations directory and did syncdb, and when I did migrate, I had to use --delete-ghost-migrations. I thought all of that would get rid of the users already in admin, but there are still the few I made up for testing. Is that correct? Also, unfortunately, the email field is still missing in the admin though I can see it in the initial migration file. – Michelle Glauser May 25 '14 at 05:16
  • Added additional detail/questions above (had been in a comment). – khampson May 25 '14 at 05:39
0

As suggested by Ken, I used "psql -h localhost -U michelleglauser db_chishenma" to get into the psql shell, then \dt to see my tables.

I looked at the Foodie model (my extended user model) using "SELECT * FROM chishenma_app_foodie;" and saw that the user email was actually included there, though it wasn't in the admin GUI. I also compared the auth_user table (using "SELECT * FROM auth_user;") to the admin GUI and saw that both had empty email fields, so it seemed that only the Foodie model was off. After digging around, I realized that all I had to do (!) was add 'user_email' to list_display in admin.py so that the email addresses, which were already being successfully saved, would show up in the admin GUI for Foodie. The full line now aligns completely with the psql table as it reads:

list_display = ('user_wechat', 'user_city', 'user_waitlist_status', 'user_waitlist_num', 'user_num_referrals', 'user_email')

Rookie mistake that caused a problem that looked a lot more complicated than it was!

Michelle Glauser
  • 1,097
  • 16
  • 28