Динамически связывать ребенка с родителем - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть две модели: модель пользователя и модель измерений. Модель измерений связана с пользовательской моделью через отношение ForeignKey. Я успешно создал форму, позволяющую создавать пользователей, но хотел бы, чтобы при просмотре этих пользователей вы могли оттуда создавать измерения без указания взаимосвязи, так как она должна автоматически использовать пользовательскую модель, отображаемую в данный момент в качестве экземпляра, и связать ее. Это было проблемой. Я попытался написать представление как это ..

View.py

def client_measurements(request, pk):
    measurement = UserModel.objects.get(id=pk)
    measurements = measurement.measurements_set.all()
    if request.method == 'POST':
        form = MeasurementsIForm(request.POST, request.FILES)

        if form.is_valid():
            form.client_name.client_name = measurement.client_name
            measure = form.save(commit=False)
            measure.instance = measurement
            measure.save()
            return HttpResponseRedirect(reverse_lazy('client', args=   [measurement.id]))
    else:
        form = MeasurementsIForm()
    return render(request, 'app/measurements.html', {'form':form,      'measurements': measurements, 'measurement': measurement}) 

Это не сохраняет в базу данных. Я новичок в django, пожалуйста, что я делаю не так?

Model.py

class UserModel(models.Model):
user_name = models.ForeignKey(User, on_delete=models.CASCADE)
client_name = models.CharField(max_length=100)
# client_lname = CapitalizeCharField(max_length=100, null=True, blank=True)
address = models.CharField(max_length=500, null=True, blank=True)
MALE = 'Male'
FEMALE = 'Female'

sex = (
    (MALE, 'Male'),
    (FEMALE, 'Female'),

)

client_gender = models.CharField(
    max_length=100,
    choices=sex,
    null=True

)
tel = models.CharField(max_length=100, null=True, blank=True)
date = models.DateTimeField(auto_now_add=True, null=True)

def __str__(self):
    return self.client_name

image = models.ImageField(upload_to=image_upload, null=True, blank=True)


def save(self, *args, **kwargs):
    super().save(*args, **kwargs)

    if self.image:
        img = Image.open(self.image.path)

        if img.width > 800 or img.height > 534:
            output_size = (300, 300)
            img.thumbnail(output_size)
            img.save(self.image.path)

def get_absolute_url(self):
    return reverse('client', kwargs={'pk': self.id})


class Measurements(models.Model):
user_name = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
client_name = models.ForeignKey(UserModel, on_delete=models.CASCADE)

DRESS = 'Dress'
SHIRT = 'Shirt'
TOUSERS = 'Trousers'
SKIRT = 'Skirt'
ATIRE = 'Native Atire'
GOWN = 'Gown'

dress_type = (
    (DRESS, 'Dress'),
    (SHIRT, 'Shirt'),
    (TOUSERS, 'Trousers'),
    (SKIRT, 'Skirt'),
    (ATIRE, 'Atire'),
    (GOWN, 'Gown'),

)

cloth_type = models.CharField(
    max_length=100,
    choices=dress_type,
    null=True

)

neck = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
over_bust = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
bust = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
under_bust = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
chest = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
crutch_depth = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
ankle = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
inseam = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
total_height = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
waist = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
hips = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
neck_to_heel = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
neck_to_above_knee = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
above_knee_to_ankle = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
arm_length = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
trouser_length = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
shoulder_seem = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
arm_hole = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
bicep = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
fore_arm = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
wrist = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
v_neck_cut = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
shoulder_to_waist = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
waist_to_above_knee = models.IntegerField(validators=[MinValueValidator(1)], blank=True, null=True)
comment = models.TextField(null=True, blank=True)
date = models.DateTimeField(auto_now_add=True, null=True)
measurement_image = models.ImageField(upload_to=measurement_image_upload, null=True, blank=True)

Form.py

class ClientForm(forms.ModelForm):
client_name = forms.RegexField(regex=re.compile(r'[A-Z][a-z]+((\s[A-Z]([a-z]+)?)?)((\s[A-Z]([a-z]+)?)?)'), required=True, error_messages={'invalid': "Each name must be Capitalized. E.g 'Kelly Roland' not 'kelly roland'"}, label="Client's Full Name")
tel = forms.RegexField(regex=re.compile(r'(080|090|070|081)[0-9]{8}'), required=False, error_messages={'invalid': "Enter a valid phone number"}, label="Phone No")
class Meta:
    model = UserModel
    widgets = {
        "tel": TextInput(),
        "client_name": TextInput(attrs={"placeholder": "Emanuel Felix Johnson"})
    }
    labels = {
        "client_name": "Client's FullName",
        "tel": "Phone No",
        "client_gender": "Gender"
    }

    fields = ('client_name', 'client_gender', 'address', 'tel', 'image' )

class MeasurementsIForm(forms.ModelForm):
class Meta:
    model = Measurements
    fields = '__all__'
    exclude = ['user_name', 'client_name']

Ответы [ 2 ]

0 голосов
/ 21 февраля 2020

Просто проверил этот код еще раз, и, используя предыдущий ответ, мне удалось заставить его работать. Я не знаю, почему это не сработало ранее, поскольку именно так я и делал изначально.

Новый просмотр

@login_required
def client_measurements(request, pk):
    client = UserModel.objects.get(id=pk)
    measurements = client.measurements_set.all()
    if request.method == 'POST':
        form = MeasurementsUpdateForm(request.POST, request.FILES)
        if form.is_valid():

            measurement = form.save(commit=False)
            measurement.user_name = request.user
            measurement.client_name = client
            measurement.save()

        return HttpResponseRedirect(reverse_lazy('client', args=   [client.id]))
else:
    form = MeasurementsUpdateForm()
return render(request, 'app/measurements.html', {'form':form, 'measurements': measurements, 'client': client}) 

Если есть лучшее решение для этого, я бы люблю знать. Спасибо.

0 голосов
/ 21 февраля 2020

Вот как я бы изменил ваше мнение, чтобы делать то, что вы хотите. Обратите внимание, что в контексте шаблона теперь клиентским ключом является пользовательский, а не measurement.

def client_measurements(request, pk):
    client = UserModel.objects.prefetch_related('measurements_set').get(id=pk)
    measurements = client.measurements_set.all()
    if request.method == 'POST':
        form = MeasurementsIForm(request.POST, request.FILES)

        if form.is_valid():
            measurement = form.save(commit=False)
            measurement.client_name = client
            measurement.save()
            return HttpResponseRedirect(reverse_lazy('client', args=   [measurement.id]))
    else:
        form = MeasurementsIForm()
    return render(request, 'app/measurements.html', {'form':form,      'measurements': measurements, 'client': client})

. В дополнение, я настоятельно рекомендую изменить модель измерений на:

class Measurement(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    client = models.ForeignKey(UserModel, on_delete=models.CASCADE)

. Свойства ForeignKey должны быть названы так, чтобы они представляли экземпляр связанных моделей, а не их свойство. При использовании ORM вы должны использовать преимущества абстракций, а не бороться с ними.

...