Estoy creando una aplicación simple que permite a los usuarios crear un grupo. Cuando el usuario crea un grupo, tiene los siguientes campos:
Mis modelos:
class Group(models.Model): groupName = models.CharField(max_length=100) description = models.CharField(max_length=255) inviteKey = models.CharField(max_length=255) class Members(models.Model): userId = models.ForeignKey(User, on_delete=models.CASCADE) groupId = models.ForeignKey(Group, on_delete=models.CASCADE) isAdmin = models.BooleanField(default=False)Forma:
class GroupForm(forms.ModelForm): groupName = forms.CharField(label='Nazwa grupy', max_length=100) description = forms.CharField(label='Opis', max_length=255) inviteKey: forms.CharField(label='Kod wstępu') class Meta: model = Group fields = ['groupName', 'description', 'inviteKey' ]Vista:
def createGroup(request): if request.method == "POST": form = GroupForm(request.POST) if form.is_valid(): form.save() messages.success(request, f'Group created') return redirect('/') else: inviteKey = generateInviteKey() form = GroupForm(initial={'inviteKey': inviteKey}) return render(request, 'group/createGroup.html',{'form': form})Ahora tengo formulario e inviteKey es visible y editable. Quiero que esta clave sea visible pero no editable.
En mi opinión, la mejor manera de hacerlo es establecer el valor predeterminado para su clave de invitación en su modelo , de esa manera, el token se crea "en segundo plano" con una clave única, pero podemos ir más allá.
Por ejemplo :
import uuid token = models.UUIDField( default=uuid.uuid4, unique=True, editable=False, )De esta manera, está seguro de que el token es único (UUID es único por diseño, pero aún así) no puede editarlo, por lo que no puede ocurrir un token incorrecto y, por último, cada objeto obtendrá un token único sin trabajo de su parte.
Estoy usando UUID porque Django lo recomienda según la Documentación para token e identificador único.
Nota: si configura el UUID con un valor predeterminado, no puede obtenerlo antes de que se cree el objeto, dependiendo de su uso, es posible que desee configurarlo en el formulario (consulte la respuesta a continuación).
Puede desactivar el campo, por lo que:
class GroupForm(forms.ModelForm): groupName = forms.CharField(label='Nazwa grupy', max_length=100) description = forms.CharField(label='Opis', max_length=255) inviteKey = forms.CharField(label='Kod wstępu' , disabled=True ) class Meta: model = Group fields = ['groupName', 'description', 'inviteKey' ]Esto también evitará que un usuario fabrique una solicitud POST que contenga una clave de invitación diferente.
Sin embargo, un problema que ahora hay que resolver es que no queremos generar una clave de inviteKey diferente cuando el usuario envía el formulario. Esto se puede manejar con datos de sesión, aunque no es una solución muy elegante. En ese caso, cambiamos la vista a:
def createGroup(request): if request.method == 'POST' and 'inviteKey' in request.session : inviteKey = request.session['inviteKey'] form = GroupForm(request.POST, initial={'inviteKey': inviteKey}) if form.is_valid(): form.save() messages.success(request, f'Group created') return redirect('/') else: request.session['inviteKey'] = inviteKey = generateInviteKey() form = GroupForm(initial={'inviteKey': inviteKey}) return render(request, 'group/createGroup.html',{'form': form}) Probablemente también desee que su campo inviteKey único, para evitar la creación de varios grupos con la misma inviteKey :
class Group(models.Model): groupName = models.CharField(max_length=100) description = models.CharField(max_length=255) inviteKey = models.CharField(max_length=255 , unique=True )