简体   繁体   中英

Django: How to register a user with “code” and pre_save signal

sorry if the title is not so descriptive, I did not know how to put it. I have two tables: 1.- The "Matricula" table which contains a code field and another "is_taken" field that is in "False" 2.- The "User" table and when registering a new user must insert an existing code in the table "Matricula", if the code exists then "is_taken" will be "True" and allow the user to register, my question is ... How can I do it ?, Which way would be the best?

I was dealing with a "pre_save" signal but without success.

models.py

class Matricula(models.Model):
    code = models.CharField(max_length=9, blank=True)
    is_taken = models.BooleanField("¿Esta ocupado?", default=False)
    created_at = models.DateTimeField("Fecha de creación", auto_now_add = True)
    updated_at = models.DateTimeField("Fecha de actualización", auto_now = True)

def __str__(self):
    return "%s" %(self.matricula)

class User(auth_models.AbstractBaseUser, auth_models.PermissionsMixin):
    code = models.CharField("Matricula", max_length=9, blank=True)
    email = models.CharField("Correo Electrónico", max_length=100, blank=True, unique=True)
    first_name = models.CharField("Nombre(s)", max_length=60, blank=True)
    last_name = models.CharField("Apellidos", max_length=60, blank=True)
    is_staff = models.BooleanField("¿Es Staff?", default=False, blank=True)
    is_active = models.BooleanField("¿Es Activo?", default=False, blank=True)
    date_joined = models.DateTimeField("Fecha de registro", auto_now_add=True)

Or could it be added in the views? in the process of user registration?

And sorry for my bad english

If you want to add a matricula for each user, you should use relations, instead of a CharField, supposing each User have only one matricula use OneToOneField :

class User(auth_models.AbstractBaseUser, auth_models.PermissionsMixin):
    matricula = models.OneToOneField(Matricula)

Well that part is easy, the problem come when you create the views, so if you create your modelform according with the relation, Django will show the existing matricula objects, so in your modelform exclude this field and in the view add the modelform of a matricula object so you can create it and save it.

def add_and_create_matricula(request):

    if request.method = 'POST':
        form_user = ModelForm_user(request.POST)
        form_matricula = ModelForm_matricula(request.POST)
        if form_user.is_valid and form_matricula.is_valid():
            matricula = form_matricula.save()
            user = form_user.save(commit=False)
            user.matricula = matricula # Here we add the realtion to the matricula
            user.save() # And save the relation

    form_user = ModelForm_user()
    form_matricula = ModelForm_matricula()
    return render(request, your_template.html, {'form_user':form_user, 'form_matricula':form_matricula})

Here I leave you an example how you should store the matricula object inside user

Try not using signals as much as possible because they hurt code readabilty by inversion of control.

As I understand your question you don't want people who do not have an invitation code, "Matricula" to be able to register on your site. You are better off doing it in your registration form. Maybe something like this:

class UserRegistrationForm(AuthRegistrationForm):
    code = forms.CharField(max_length=9)

    def clean(self):
        cleaned_data = super(ContactForm, self).clean()
        try:
            matricula = Matricula.objects.get(code=cleaned_data.get('code', None), is_taken=False)
        except ObjectDoesNotExist:
            raise forms.ValidationError('Invalid code')
        else:
            cleaned_data['code'] = matricula

        return cleaned_data



# in your views:

.... if form.is_valid():
      matricula = form.cleaned_data['code']
      matricula.is_taken = True
      matricula.save()
      new_user = form.save()
.....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM